Cataclysm BN
map Class Reference

Manage and cache data about a part of the map. More...

#include <map.h>

Inheritance diagram for map:
tinymap fake_map

Classes

struct  apparent_light_info
 

Public Member Functions

 map (int mapsize=MAPSIZE, bool zlev=false)
 
 map (bool zlev)
 
virtual ~map ()
 
mapoperator= (const map &)=delete
 
mapoperator= (map &&)
 
void set_transparency_cache_dirty (const int zlev)
 Sets a dirty flag on the a given cache. More...
 
void set_transparency_cache_dirty (const tripoint &p)
 
void set_seen_cache_dirty (const tripoint change_location)
 
void set_seen_cache_dirty (const int zlevel)
 
void set_outside_cache_dirty (const int zlev)
 
void set_floor_cache_dirty (const int zlev)
 
void set_suspension_cache_dirty (const int zlev)
 
void set_pathfinding_cache_dirty (int zlev)
 
void set_memory_seen_cache_dirty (const tripoint &p)
 
void invalidate_map_cache (const int zlev)
 
bool check_seen_cache (const tripoint &p) const
 
bool check_and_set_seen_cache (const tripoint &p) const
 
void on_vehicle_moved (int smz)
 Callback invoked when a vehicle has moved. More...
 
lit_level apparent_light_at (const tripoint &p, const visibility_variables &cache) const
 Determine the visible light level for a tile, based on light_at for the tile, vision distance, etc. More...
 
visibility_type get_visibility (lit_level ll, const visibility_variables &cache) const
 
std::tuple< maptile, maptile, maptileget_wind_blockers (const int &winddirection, const tripoint &pos)
 
void draw (const catacurses::window &w, const tripoint &center)
 Draw a visible part of the map into w. More...
 
void drawsq (const catacurses::window &w, const tripoint &p, const drawsq_params &params) const
 Draw the map tile at the given coordinate. More...
 
void save ()
 Add currently loaded submaps (in grid) to the mapbuffer. More...
 
void load (const tripoint &w, bool update_vehicles, bool pump_events=false)
 Load submaps into grid. More...
 
void load (const tripoint_abs_sm &w, bool update_vehicles, bool pump_events=false)
 
void shift (point s)
 Shift the map along the vector s. More...
 
void vertical_shift (int newz)
 Moves the map vertically to (not by!) newz. More...
 
void clear_spawns ()
 
void clear_traps ()
 
maptile maptile_at (const tripoint &p) const
 
maptile maptile_at (const tripoint &p)
 
int move_cost (const tripoint &p, const vehicle *ignored_vehicle=nullptr) const
 Calculate the cost to move past the tile at p. More...
 
int move_cost (point p, const vehicle *ignored_vehicle=nullptr) const
 
bool impassable (const tripoint &p) const
 
bool impassable (point p) const
 
bool passable (const tripoint &p) const
 
bool passable (point p) const
 
bool is_wall_adjacent (const tripoint &center) const
 
int move_cost_ter_furn (const tripoint &p) const
 Similar behavior to move_cost(), but ignores vehicles. More...
 
int move_cost_ter_furn (point p) const
 
bool impassable_ter_furn (const tripoint &p) const
 
bool passable_ter_furn (const tripoint &p) const
 
int combined_movecost (const tripoint &from, const tripoint &to, const vehicle *ignored_vehicle=nullptr, int modifier=0, bool flying=false, bool via_ramp=false) const
 Cost to move out of one tile and into the next. More...
 
bool valid_move (const tripoint &from, const tripoint &to, bool bash=false, bool flying=false, bool via_ramp=false) const
 Returns true if a creature could walk from from to to in one step. More...
 
double ranged_target_size (const tripoint &p) const
 Size of map objects at p for purposes of ranged combat. More...
 
bool sees (const tripoint &F, const tripoint &T, int range) const
 Returns whether F sees T with a view range of range. More...
 
int obstacle_coverage (const tripoint &loc1, const tripoint &loc2) const
 Returns coverage of target in relation to the observer. More...
 
int coverage (const tripoint &p) const
 Returns coverage value of the tile. More...
 
bool clear_path (const tripoint &f, const tripoint &t, int range, int cost_min, int cost_max) const
 Check whether there's a direct line of sight between F and T with the additional movecost restraints. More...
 
bool obstructed_by_vehicle_rotation (const tripoint &from, const tripoint &to) const
 Checks if a rotated vehicle is blocking diagonal movement, tripoints must be adjacent. More...
 
bool obscured_by_vehicle_rotation (const tripoint &from, const tripoint &to) const
 Checks if a rotated vehicle is blocking diagonal vision, tripoints must be adjacent. More...
 
void reachable_flood_steps (std::vector< tripoint > &reachable_pts, const tripoint &f, int range, int cost_min, int cost_max) const
 Populates a vector of points that are reachable within a number of steps from a point. More...
 
std::vector< tripointfind_clear_path (const tripoint &source, const tripoint &destination) const
 Iteratively tries Bresenham lines with different biases until it finds a clear line or decides there isn't one. More...
 
bool accessible_items (const tripoint &t) const
 Check whether the player can access the items located . More...
 
std::vector< tripointget_dir_circle (const tripoint &f, const tripoint &t) const
 Calculate next search points surrounding the current position. More...
 
std::vector< tripointroute (const tripoint &f, const tripoint &t, const pathfinding_settings &settings, const std::set< tripoint > &pre_closed={{ }}) const
 Calculate the best path using A*. More...
 
VehicleList get_vehicles ()
 
void add_vehicle_to_cache (vehicle *)
 
void clear_vehicle_point_from_cache (vehicle *veh, const tripoint &pt)
 
void update_vehicle_cache (vehicle *, int old_zlevel)
 
void reset_vehicle_cache ()
 
void clear_vehicle_cache ()
 
void clear_vehicle_list (int zlev)
 
void update_vehicle_list (const submap *to, int zlev)
 
bool check_vehicle_zones (int zlev)
 
std::vector< zone_data * > get_vehicle_zones (int zlev)
 
void register_vehicle_zone (vehicle *, int zlev)
 
bool deregister_vehicle_zone (zone_data &zone)
 
std::unique_ptr< vehicledetach_vehicle (vehicle *veh)
 
void destroy_vehicle (vehicle *veh)
 
void vehmove ()
 
bool vehproceed (VehicleList &vehicle_list)
 
VehicleList get_vehicles (const tripoint &start, const tripoint &end)
 
optional_vpart_position veh_at (const tripoint &p) const
 Checks if tile is occupied by vehicle and by which part. More...
 
vehicleveh_at_internal (const tripoint &p, int &part_num)
 
const vehicleveh_at_internal (const tripoint &p, int &part_num) const
 
void board_vehicle (const tripoint &p, player *pl)
 
void unboard_vehicle (const vpart_reference &, Character *passenger, bool dead_passenger=false)
 
void unboard_vehicle (const tripoint &p, bool dead_passenger=false)
 
bool displace_vehicle (vehicle &veh, const tripoint &dp)
 
void shift_vehicle_z (vehicle &veh, int z_shift)
 
bool displace_water (const tripoint &dp)
 
float vehicle_wheel_traction (const vehicle &veh, bool ignore_movement_modifiers=false) const
 
float vehicle_vehicle_collision (vehicle &veh, vehicle &veh2, const std::vector< veh_collision > &collisions)
 
units::angle shake_vehicle (vehicle &veh, int velocity_before, units::angle direction)
 
vehiclemove_vehicle (vehicle &veh, const tripoint &dp, const tileray &facing)
 
void set (const tripoint &p, const ter_id &new_terrain, const furn_id &new_furniture)
 
void set (point p, const ter_id &new_terrain, const furn_id &new_furniture)
 
std::string name (const tripoint &p)
 
std::string name (point p)
 
std::string disp_name (const tripoint &p)
 
std::string obstacle_name (const tripoint &p)
 Returns the name of the obstacle at p that might be blocking movement/projectiles/etc. More...
 
bool has_furn (const tripoint &p) const
 
bool has_furn (point p) const
 
furn_id furn (const tripoint &p) const
 
furn_id furn (point p) const
 
void furn_set (const tripoint &p, const furn_id &new_furniture, cata::poly_serialized< active_tile_data > new_active=nullptr)
 Sets the furniture at given position. More...
 
void furn_set (point p, const furn_id &new_furniture)
 
std::string furnname (const tripoint &p)
 
std::string furnname (point p)
 
bool can_move_furniture (const tripoint &pos, player *p=nullptr)
 
ter_id ter (const tripoint &p) const
 
ter_id ter (point p) const
 
uint8_t get_known_connections (const tripoint &p, int connect_group, const std::map< tripoint, ter_id > &override={}) const
 
const harvest_idget_harvest (const tripoint &p) const
 Returns the full harvest list, for spawning. More...
 
const std::set< std::string > & get_harvest_names (const tripoint &p) const
 Returns names of the items that would be dropped. More...
 
ter_id get_ter_transforms_into (const tripoint &p) const
 
furn_id get_furn_transforms_into (const tripoint &p) const
 
bool ter_set (const tripoint &p, const ter_id &new_terrain)
 
bool ter_set (point p, const ter_id &new_terrain)
 
std::string tername (const tripoint &p) const
 
std::string tername (point p) const
 
bool has_nearby_fire (const tripoint &p, int radius=1)
 
bool has_nearby_table (const tripoint &p, int radius=1)
 Check whether a table/workbench/vehicle kitchen or other flat surface is nearby that could be used for crafting or eating. More...
 
bool has_nearby_chair (const tripoint &p, int radius=1)
 Check whether a chair or vehicle seat is nearby. More...
 
bool sees_some_items (const tripoint &p, const Creature &who) const
 Check if creature can see some items at p. More...
 
bool sees_some_items (const tripoint &p, const tripoint &from) const
 
bool could_see_items (const tripoint &p, const Creature &who) const
 Check if the creature could see items at p if there were any items. More...
 
bool could_see_items (const tripoint &p, const tripoint &from) const
 
bool has_items (const tripoint &p) const
 Checks for existence of items. More...
 
void examine (Character &p, const tripoint &pos)
 Calls the examine function of furniture or terrain at given tile, for given character. More...
 
bool is_harvestable (const tripoint &pos) const
 Returns true if point at pos is harvestable right now, with no extra tools. More...
 
std::string features (const tripoint &p)
 
std::string features (point p)
 
bool has_flag (const std::string &flag, const tripoint &p) const
 
bool has_flag (const std::string &flag, point p) const
 
bool can_put_items (const tripoint &p) const
 
bool can_put_items (point p) const
 
bool can_put_items_ter_furn (const tripoint &p) const
 
bool can_put_items_ter_furn (point p) const
 
bool has_flag_ter (const std::string &flag, const tripoint &p) const
 
bool has_flag_ter (const std::string &flag, point p) const
 
bool has_flag_furn (const std::string &flag, const tripoint &p) const
 
bool has_flag_furn (const std::string &flag, point p) const
 
bool has_flag_vpart (const std::string &flag, const tripoint &p) const
 
bool has_flag_furn_or_vpart (const std::string &flag, const tripoint &p) const
 
bool has_flag_ter_or_furn (const std::string &flag, const tripoint &p) const
 
bool has_flag_ter_or_furn (const std::string &flag, point p) const
 
bool has_flag (ter_bitflags flag, const tripoint &p) const
 
bool has_flag (ter_bitflags flag, point p) const
 
bool has_flag_ter (ter_bitflags flag, const tripoint &p) const
 
bool has_flag_ter (ter_bitflags flag, point p) const
 
bool has_flag_furn (ter_bitflags flag, const tripoint &p) const
 
bool has_flag_furn (ter_bitflags flag, point p) const
 
bool has_flag_ter_or_furn (ter_bitflags flag, const tripoint &p) const
 
bool has_flag_ter_or_furn (ter_bitflags flag, point p) const
 
bool is_bashable (const tripoint &p, bool allow_floor=false) const
 Returns true if there is a bashable vehicle part or the furn/terrain is bashable at p. More...
 
bool is_bashable (point p) const
 
bool is_bashable_ter (const tripoint &p, bool allow_floor=false) const
 Returns true if the terrain at p is bashable. More...
 
bool is_bashable_ter (point p) const
 
bool is_bashable_furn (const tripoint &p) const
 Returns true if the furniture at p is bashable. More...
 
bool is_bashable_furn (point p) const
 
bool is_bashable_ter_furn (const tripoint &p, bool allow_floor=false) const
 Returns true if the furniture or terrain at p is bashable. More...
 
bool is_bashable_ter_furn (point p) const
 
int bash_strength (const tripoint &p, bool allow_floor=false) const
 Returns max_str of the furniture or terrain at p. More...
 
int bash_strength (point p) const
 
int bash_resistance (const tripoint &p, bool allow_floor=false) const
 Returns min_str of the furniture or terrain at p. More...
 
int bash_resistance (point p) const
 
int bash_rating (int str, const tripoint &p, bool allow_floor=false) const
 Returns a success rating from -1 to 10 for a given tile based on a set strength, used for AI movement planning Values roughly correspond to 10% increment chances of success on a given bash, rounded down. More...
 
int bash_rating (const int str, point p) const
 
void make_rubble (const tripoint &p, const furn_id &rubble_type, bool items, const ter_id &floor_type, bool overwrite=false)
 Generates rubble at the given location, if overwrite is true it just writes on top of what currently exists floor_type is only used if there is a non-bashable wall at the location or with overwrite = true. More...
 
void make_rubble (const tripoint &p, const furn_id &rubble_type, bool items)
 
void make_rubble (const tripoint &p)
 
bool is_outside (const tripoint &p) const
 
bool is_outside (point p) const
 
bool is_divable (const tripoint &p) const
 Returns whether or not the terrain at the given location can be dived into (by monsters that can swim or are aquatic or non-breathing). More...
 
bool is_divable (point p) const
 
bool is_water_shallow_current (const tripoint &p) const
 
bool is_water_shallow_current (point p) const
 
bool is_last_ter_wall (bool no_furn, point p, point max, direction dir) const
 Check if the last terrain is wall in direction NORTH, SOUTH, WEST or EAST. More...
 
bool tinder_at (const tripoint &p)
 Checks if there are any tinder flagged items on the tile. More...
 
bool flammable_items_at (const tripoint &p, int threshold=0)
 Checks if there are any flammable items on the tile. More...
 
bool is_flammable (const tripoint &p)
 Returns true if there is a flammable item or field or the furn/terrain is flammable at p. More...
 
point random_outdoor_tile ()
 
void draw_line_ter (const ter_id &type, point p1, point p2)
 
void draw_line_furn (const furn_id &type, point p1, point p2)
 
void draw_fill_background (const ter_id &type)
 
void draw_fill_background (ter_id(*f)())
 
void draw_fill_background (const weighted_int_list< ter_id > &f)
 
void draw_square_ter (const ter_id &type, point p1, point p2)
 
void draw_square_furn (const furn_id &type, point p1, point p2)
 
void draw_square_ter (ter_id(*f)(), point p1, point p2)
 
void draw_square_ter (const weighted_int_list< ter_id > &f, point p1, point p2)
 
void draw_rough_circle_ter (const ter_id &type, point p, int rad)
 
void draw_rough_circle_furn (const furn_id &type, point p, int rad)
 
void draw_circle_ter (const ter_id &type, const rl_vec2d &p, double rad)
 
void draw_circle_ter (const ter_id &type, point p, int rad)
 
void draw_circle_furn (const furn_id &type, point p, int rad)
 
void add_corpse (const tripoint &p)
 
void translate (const ter_id &from, const ter_id &to)
 
void translate_radius (const ter_id &from, const ter_id &to, float radi, const tripoint &p, bool same_submap=false, bool toggle_between=false)
 
bool close_door (const tripoint &p, bool inside, bool check_only)
 
bool open_door (const tripoint &p, bool inside, bool check_only=false)
 
void batter (const tripoint &p, int power, int tries=1, bool silent=false)
 bash a square for a set number of times at set power. More...
 
void destroy (const tripoint &p, bool silent=false)
 Keeps bashing a square until it can't be bashed anymore. More...
 
void destroy_furn (const tripoint &p, bool silent=false)
 Keeps bashing a square until there is no more furniture. More...
 
void crush (const tripoint &p)
 
void shoot (const tripoint &p, projectile &proj, bool hit_items)
 
int collapse_check (const tripoint &p)
 Checks if a square should collapse, returns the X for the one_in(X) collapse chance. More...
 
void collapse_at (const tripoint &p, bool silent, bool was_supporting=false, bool destroy_pos=true)
 Causes a collapse at p, such as from destroying a wall. More...
 
void propagate_suspension_check (const tripoint &point)
 Checks surrounding tiles for suspension, and has them check for collapse. More...
 
void collapse_invalid_suspension (const tripoint &point)
 Triggers a recursive collapse of suspended tiles based on their support validity. More...
 
bool is_suspension_valid (const tripoint &point)
 Checks the four orientations in which a suspended tile could be valid, and returns if the tile is valid. More...
 
void smash_items (const tripoint &p, int power, const std::string &cause_message, bool do_destroy)
 Tries to smash the items at the given tripoint. More...
 
bash_results bash (const tripoint &p, int str, bool silent=false, bool destroy=false, bool bash_floor=false, const vehicle *bashing_vehicle=nullptr)
 Returns a pair where first is whether anything was smashed and second is if it was destroyed. More...
 
bash_results bash_vehicle (const tripoint &p, const bash_params &params)
 
bash_results bash_ter_furn (const tripoint &p, const bash_params &params)
 
bool hit_with_acid (const tripoint &p)
 
bool hit_with_fire (const tripoint &p)
 
bool has_adjacent_furniture_with (const tripoint &p, const std::function< bool(const furn_t &)> &filter)
 Returns true if there is furniture for which filter returns true in a 1 tile radius of p. More...
 
bool mop_spills (const tripoint &p)
 Remove moppable fields/items at this location. More...
 
void decay_fields_and_scent (const time_duration &amount)
 Moved here from weather.cpp for speed. More...
 
std::string get_signage (const tripoint &p) const
 
void set_signage (const tripoint &p, const std::string &message) const
 
void delete_signage (const tripoint &p) const
 
int get_radiation (const tripoint &p) const
 
void set_radiation (const tripoint &p, int value)
 
void set_radiation (point p, const int value)
 
void adjust_radiation (const tripoint &p, int delta)
 Increment the radiation in the given tile by the given delta (decrement it if delta is negative) More...
 
void adjust_radiation (point p, const int delta)
 
int get_temperature (const tripoint &p) const
 
void set_temperature (const tripoint &p, int temperature)
 
void set_temperature (point p, int new_temperature)
 
std::vector< tripointcheck_submap_active_item_consistency ()
 
map_stack i_at (const tripoint &p)
 
map_stack i_at (point p)
 
item water_from (const tripoint &p)
 
void i_clear (const tripoint &p)
 
void i_clear (point p)
 
map_stack::iterator i_rem (const tripoint &p, map_stack::const_iterator it)
 
map_stack::iterator i_rem (point location, map_stack::const_iterator it)
 
void i_rem (const tripoint &p, item *it)
 
void i_rem (point p, item *it)
 
void spawn_artifact (const tripoint &p)
 
void spawn_natural_artifact (const tripoint &p, artifact_natural_property prop)
 
void spawn_item (const tripoint &p, const itype_id &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
 
void spawn_item (point p, const itype_id &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
 
void spawn_item (const tripoint &p, const std::string &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
 
void spawn_item (point p, const std::string &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
 
units::volume max_volume (const tripoint &p)
 
units::volume free_volume (const tripoint &p)
 
units::volume stored_volume (const tripoint &p)
 
itemadd_item_or_charges (const tripoint &pos, item obj, bool overflow=true)
 Adds an item to map tile or stacks charges. More...
 
itemadd_item_or_charges (point p, item obj, bool overflow=true)
 
itemadd_item (const tripoint &p, item new_item)
 Place an item on the map, despite the parameter name, this is not necessarily a new item. More...
 
void add_item (point p, item new_item)
 
itemspawn_an_item (const tripoint &p, item new_item, int charges, int damlevel)
 
void spawn_an_item (point p, item new_item, int charges, int damlevel)
 
void make_active (item_location &loc)
 Update an item's active status, for example when adding hot or perishable liquid to a container. More...
 
void update_lum (item_location &loc, bool add)
 Update luminosity before and after item's transformation. More...
 

Static Public Member Functions

static apparent_light_info apparent_light_helper (const level_cache &map_cache, const tripoint &p)
 Helper function for light claculation; exposed here for map editor. More...
 

Private Member Functions

maptile maptile_at_internal (const tripoint &p) const
 
maptile maptile_at_internal (const tripoint &p)
 
std::pair< tripoint, maptilemaptile_has_bounds (const tripoint &p, bool bounds_checked)
 
std::array< std::pair< tripoint, maptile >, 8 > get_neighbors (const tripoint &p)
 
void spread_gas (field_entry &cur, const tripoint &p, int percent_spread, const time_duration &outdoor_age_speedup, scent_block &sblk)
 
void create_hot_air (const tripoint &p, int intensity)
 
bool gas_can_spread_to (field_entry &cur, const tripoint &src, const tripoint &dst)
 
void gas_spread_to (field_entry &cur, maptile &dst, const tripoint &p)
 
int burn_body_part (player &u, field_entry &cur, body_part bp, int scale)
 
bool sees (const tripoint &F, const tripoint &T, int range, int &bresenham_slope) const
 Don't expose the slope adjust outside map functions. More...
 

Friends

class editmap
 
class visitable< map_cursor >
 

Consume items on the map

The functions here consume accessible items / item charges on the map or in vehicles around the player (whose positions is given as origin).

They return a list of copies of the consumed items (with the actually consumed charges in it). The quantity / amount parameter will be reduced by the number of items/charges removed. If all required items could be removed from the map, the quantity/amount will be 0, otherwise it will contain a positive value and the remaining items must be gathered from somewhere else.

enum  iteration_state { ITER_CONTINUE = 0 , ITER_SKIP_SUBMAP , ITER_SKIP_ZLEVEL , ITER_FINISH }
 Enum used by functors in function_over to control execution. More...
 
std::set< tripointsupport_cache_dirty
 
std::vector< submap * > grid
 The list of currently loaded submaps. More...
 
std::vector< std::vector< tripoint > > traplocs
 This vector contains an entry for each trap type, it has therefor the same size as the traplist vector. More...
 
std::vector< tripointfield_furn_locs
 Vector of tripoints containing active field-emitting furniture. More...
 
std::array< std::unique_ptr< level_cache >, OVERMAP_LAYERScaches
 Holds caches for visibility, light, transparency and vehicles. More...
 
std::array< std::unique_ptr< pathfinding_cache >, OVERMAP_LAYERSpathfinding_caches
 
std::set< tripointsubmaps_with_active_items
 Set of submaps that contain active items in absolute coordinates. More...
 
lru_cache< point, char > skew_vision_cache
 Cache of coordinate pairs recently checked for visibility. More...
 
VehicleList last_full_vehicle_list
 Vehicle list doesn't change often, but is pretty expensive. More...
 
bool last_full_vehicle_list_dirty = true
 
visibility_variables visibility_variables_cache
 
cata::optional< std::pair< tripoint, int > > max_populated_zlev = cata::nullopt
 
std::set< vehicle * > dirty_vehicle_list
 
int my_MAPSIZE
 
bool zlevels
 
vision_adjustment vision_transparency_cache [8] = { VISION_ADJUST_NONE }
 
tripoint abs_sub
 Absolute coordinates of first submap (get_submap_at(0,0)) This is in submap coordinates (see overmapbuffer for explanation). More...
 
std::list< itemuse_amount_square (const tripoint &p, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter=return_true< item >)
 
std::list< itemuse_amount (const tripoint &origin, int range, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter=return_true< item >)
 
std::list< itemuse_charges (const tripoint &origin, int range, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter=return_true< item >, basecamp *bcp=nullptr)
 
std::vector< item * > place_items (const item_group_id &loc, int chance, const tripoint &p1, const tripoint &p2, bool ongrass, const time_point &turn, int magazine=0, int ammo=0)
 Place items from item group in the rectangle f - t. More...
 
std::vector< item * > place_items (const item_group_id &loc, int chance, point p1, point p2, bool ongrass, const time_point &turn, int magazine=0, int ammo=0)
 
std::vector< item * > put_items_from_loc (const item_group_id &loc, const tripoint &p, const time_point &turn=calendar::start_of_cataclysm)
 Place items from an item group at p. More...
 
std::vector< item * > spawn_items (const tripoint &p, const std::vector< item > &new_items)
 
void spawn_items (point p, const std::vector< item > &new_items)
 
void create_anomaly (const tripoint &p, artifact_natural_property prop, bool create_rubble=true)
 
void create_anomaly (point cp, artifact_natural_property prop, bool create_rubble=true)
 
void partial_con_set (const tripoint &p, const partial_con &con)
 
void partial_con_remove (const tripoint &p)
 
partial_conpartial_con_at (const tripoint &p)
 
void trap_set (const tripoint &p, const trap_id &type)
 
const traptr_at (const tripoint &p) const
 
bool can_see_trap_at (const tripoint &p, const Character &c) const
 See trap::can_see, which is called for the trap here. More...
 
void disarm_trap (const tripoint &p)
 
void remove_trap (const tripoint &p)
 
const std::vector< tripoint > & get_furn_field_locations () const
 
const std::vector< tripoint > & trap_locations (const trap_id &type) const
 
void create_burnproducts (const tripoint &p, const item &fuel, const units::mass &burned_mass)
 
void process_fields ()
 
void process_fields_in_submap (submap *current_submap, const tripoint &submap_pos)
 
void creature_in_field (Creature &critter)
 Apply field effects to the creature when it's on a square with fields. More...
 
void creature_on_trap (Creature &critter, bool may_avoid=true)
 Apply trap effects to the creature, similar to creature_in_field. More...
 
const fieldfield_at (const tripoint &p) const
 Get the fields that are here. More...
 
fieldfield_at (const tripoint &p)
 Gets fields that are here. More...
 
time_duration get_field_age (const tripoint &p, const field_type_id &type) const
 Get the age of a field entry (field_entry::age), if there is no field of that type, returns -1_turns. More...
 
int get_field_intensity (const tripoint &p, const field_type_id &type) const
 Get the intensity of a field entry (field_entry::intensity), if there is no field of that type, returns 0. More...
 
time_duration mod_field_age (const tripoint &p, const field_type_id &type, const time_duration &offset)
 Increment/decrement age of field entry at point. More...
 
int mod_field_intensity (const tripoint &p, const field_type_id &type, int offset)
 Increment/decrement intensity of field entry at point, creating if not present, removing if intensity becomes 0. More...
 
time_duration set_field_age (const tripoint &p, const field_type_id &type, const time_duration &age, bool isoffset=false)
 Set age of field entry at point. More...
 
int set_field_intensity (const tripoint &p, const field_type_id &type, int new_intensity, bool isoffset=false)
 Set intensity of field entry at point, creating if not present, removing if intensity becomes 0. More...
 
field_entryget_field (const tripoint &p, const field_type_id &type)
 Get field of specific type at point. More...
 
bool dangerous_field_at (const tripoint &p)
 
bool add_field (const tripoint &p, const field_type_id &type_id, int intensity=INT_MAX, const time_duration &age=0_turns, bool hit_player=true)
 Add field entry at point, or set intensity if present. More...
 
void remove_field (const tripoint &p, const field_type_id &field_to_remove)
 Remove field entry at xy, ignored if the field entry is not present. More...
 
void add_splatter (const field_type_id &type, const tripoint &where, int intensity=1)
 
void add_splatter_trail (const field_type_id &type, const tripoint &from, const tripoint &to)
 
void add_splash (const field_type_id &type, const tripoint &center, int radius, int intensity)
 
void propagate_field (const tripoint &center, const field_type_id &type, int amount, int max_intensity=0)
 
void emit_field (const tripoint &pos, const emit_id &src, float mul=1.0f)
 Runs one cycle of emission src which may result in propagation of fields. More...
 
void scent_blockers (std::array< std::array< char, MAPSIZE_X >, MAPSIZE_Y > &scent_transfer, point min, point max)
 Build the map of scent-resistant tiles. More...
 
computercomputer_at (const tripoint &p)
 
computeradd_computer (const tripoint &p, const std::string &name, int security)
 
void add_camp (const tripoint_abs_omt &omt_pos, const std::string &name)
 
void remove_submap_camp (const tripoint &)
 
basecamp hoist_submap_camp (const tripoint &p)
 
bool point_within_camp (const tripoint &point_check) const
 
bool has_graffiti_at (const tripoint &p) const
 
const std::string & graffiti_at (const tripoint &p) const
 
void set_graffiti (const tripoint &p, const std::string &contents)
 
void delete_graffiti (const tripoint &p)
 
int climb_difficulty (const tripoint &p) const
 Checks 3x3 block centered on p for terrain to climb. More...
 
bool has_floor (const tripoint &p) const
 
bool supports_above (const tripoint &p) const
 Does this tile support vehicles and furniture above it. More...
 
bool has_floor_or_support (const tripoint &p) const
 
void drop_everything (const tripoint &p)
 Handles map objects of given type (not creatures) falling down. More...
 
void drop_furniture (const tripoint &p)
 
void drop_items (const tripoint &p)
 
void drop_vehicle (const tripoint &p)
 
void drop_fields (const tripoint &p)
 
void process_falling ()
 Invoked drop_everything on cached dirty tiles. More...
 
bool is_cornerfloor (const tripoint &p) const
 
void generate (const tripoint &p, const time_point &when)
 
void place_spawns (const mongroup_id &group, int chance, point p1, point p2, float density, bool individual=false, bool friendly=false, const std::string &name="NONE", int mission_id=-1)
 
void place_gas_pump (point p, int charges, const std::string &fuel_type)
 
void place_gas_pump (point p, int charges)
 
void place_toilet (point p, int charges=6 *4)
 
void place_vending (point p, const item_group_id &type, bool reinforced=false)
 
character_id place_npc (point p, const string_id< npc_template > &type, bool force=false)
 
void apply_faction_ownership (point p1, point p2, const faction_id &id)
 
void add_spawn (const mtype_id &type, int count, const tripoint &p, bool friendly=false, int faction_id=-1, int mission_id=-1, const std::string &name="NONE") const
 
void do_vehicle_caching (int z)
 
void build_map_cache (int zlev, bool skip_lightmap=false)
 
void build_obstacle_cache (const tripoint &start, const tripoint &end, float(&obstacle_cache)[MAPSIZE_X][MAPSIZE_Y])
 
vehicleadd_vehicle (const vgroup_id &type, const tripoint &p, units::angle dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
 
vehicleadd_vehicle (const vgroup_id &type, point p, units::angle dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
 
vehicleadd_vehicle (const vproto_id &type, const tripoint &p, units::angle dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
 
vehicleadd_vehicle (const vproto_id &type, point p, units::angle dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
 
float light_transparency (const tripoint &p) const
 
lit_level light_at (const tripoint &p) const
 
float ambient_light_at (const tripoint &p) const
 
bool is_transparent (const tripoint &p) const
 Returns whether the tile at p is transparent(you can look past it). More...
 
bool pl_sees (const tripoint &t, int max_range) const
 Whether the player character (g->u) can see the given square (local map coordinates). More...
 
bool pl_line_of_sight (const tripoint &t, int max_range) const
 Uses the map cache to tell if the player could see the given square. More...
 
tripoint get_abs_sub () const
 return abs_sub More...
 
tripoint getabs (const tripoint &p) const
 Translates local (to this map) coordinates of a square to global absolute coordinates. More...
 
point getabs (point p) const
 
tripoint getlocal (const tripoint &p) const
 Inverse of getabs. More...
 
point getlocal (point p) const
 
virtual bool inbounds (const tripoint &p) const
 
bool inbounds (point p) const
 
bool inbounds_z (const int z) const
 
void clip_to_bounds (tripoint &p) const
 Clips the coordinates of p to fit the map bounds. More...
 
void clip_to_bounds (int &x, int &y) const
 
void clip_to_bounds (int &x, int &y, int &z) const
 
int getmapsize () const
 
bool has_zlevels () const
 
void rotate (int turns, bool setpos_safe=false)
 Rotates this map, and all of its contents, by the specified multiple of 90 degrees. More...
 
void spawn_monsters (bool ignore_sight)
 Spawn monsters from submap spawn points and from the overmap. More...
 
void rotten_item_spawn (const item &item, const tripoint &p)
 Checks to see if the item that is rotting away generates a creature when it does. More...
 
void build_outside_cache (int zlev)
 
bool build_floor_cache (int zlev)
 
void build_floor_caches ()
 
void update_suspension_cache (const int &z)
 
bash_results bash_items (const tripoint &p, const bash_params &params)
 
bash_results bash_field (const tripoint &p, const bash_params &params)
 
bash_results bash_ter_success (const tripoint &p, const bash_params &params)
 
bash_results bash_furn_success (const tripoint &p, const bash_params &params)
 
void process_items ()
 
const level_cacheget_cache_ref (int zlev) const
 
const pathfinding_cacheget_pathfinding_cache_ref (int zlev) const
 
void update_pathfinding_cache (int zlev) const
 
void update_visibility_cache (int zlev)
 
const visibility_variablesget_visibility_variables_cache () const
 
void update_submap_active_item_status (const tripoint &p)
 
const std::set< tripoint > & get_submaps_with_active_items () const
 
tripoint_range< tripointpoints_in_rectangle (const tripoint &from, const tripoint &to) const
 
tripoint_range< tripointpoints_in_radius (const tripoint &center, size_t radius, size_t radiusz=0) const
 
tripoint_range< tripointpoints_on_zlevel () const
 Yields a range of all points that are contained in the map and have the z-level of this map (abs_sub). More...
 
tripoint_range< tripointpoints_on_zlevel (int z) const
 Same as above, but uses the specific z-level. More...
 
std::list< item_locationget_active_items_in_radius (const tripoint &center, int radius) const
 
std::list< item_locationget_active_items_in_radius (const tripoint &center, int radius, special_item_type type) const
 
std::list< tripointfind_furnitures_with_flag_in_radius (const tripoint &center, size_t radius, const std::string &flag, size_t radiusz=0)
 returns positions of furnitures with matching flag in the specified radius More...
 
std::list< tripointfind_furnitures_or_vparts_with_flag_in_radius (const tripoint &center, size_t radius, const std::string &flag, size_t radiusz=0)
 returns positions of furnitures or vehicle parts with matching flag in the specified radius More...
 
std::list< Creature * > get_creatures_in_radius (const tripoint &center, size_t radius, size_t radiusz=0)
 returns creatures in specified radius More...
 
level_cacheaccess_cache (int zlev)
 
const level_cacheaccess_cache (int zlev) const
 
bool dont_draw_lower_floor (const tripoint &p)
 
void support_dirty (const tripoint &p)
 
void spawn_monsters_submap (const tripoint &gp, bool ignore_sight)
 
void spawn_monsters_submap_group (const tripoint &gp, mongroup &group, bool ignore_sight)
 
fieldget_field (const tripoint &p)
 
submapgetsubmap (size_t grididx) const
 Get the submap pointer with given index in grid, the index must be valid! More...
 
submapget_submap_at (const tripoint &p) const
 Get the submap pointer containing the specified position within the reality bubble. More...
 
submapget_submap_at (point p) const
 
submapget_submap_at (const tripoint &p, point &offset_p) const
 Get the submap pointer containing the specified position within the reality bubble. More...
 
submapget_submap_at (point p, point &offset_p) const
 
submapget_submap_at_grid (point gridp) const
 Get submap pointer in the grid at given grid coordinates. More...
 
submapget_submap_at_grid (const tripoint &gridp) const
 
int calc_max_populated_zlev ()
 Caclulate the greatest populated zlevel in the loaded submaps and save in the level cache. More...
 
void invalidate_max_populated_zlev (int zlev)
 Conditionally invalidates max_pupulated_zlev cache if the submap uniformity change occurs above current max_pupulated_zlev value. More...
 
int move_cost_internal (const furn_t &furniture, const ter_t &terrain, const vehicle *veh, int vpart) const
 Internal versions of public functions to avoid checking same variables multiple times. More...
 
int bash_rating_internal (int str, const furn_t &furniture, const ter_t &terrain, bool allow_floor, const vehicle *veh, int part) const
 
bool draw_maptile (const catacurses::window &w, const tripoint &p, const maptile &tile, const drawsq_params &params) const
 Internal version of the drawsq. More...
 
void draw_from_above (const catacurses::window &w, const tripoint &p, const maptile &tile, const drawsq_params &params) const
 Draws the tile as seen from above. More...
 
int determine_wall_corner (const tripoint &p) const
 
void apply_light_source (const tripoint &p, float luminance)
 
void add_light_source (const tripoint &p, float luminance)
 
void apply_directional_light (const tripoint &p, int direction, float luminance)
 
void apply_light_arc (const tripoint &p, units::angle, float luminance, units::angle wideangle=30_degrees)
 
void apply_light_ray (bool lit[MAPSIZE_X][MAPSIZE_Y], const tripoint &s, const tripoint &e, float luminance)
 
void add_light_from_items (const tripoint &p, item_stack::iterator begin, item_stack::iterator end)
 
std::unique_ptr< vehicleadd_vehicle_to_map (std::unique_ptr< vehicle > veh, bool merge_wrecks)
 Takes a vehicle already created with new and attempts to place it on the map, checking for collisions. More...
 
ter_id get_roof (const tripoint &p, bool allow_air) const
 
void process_items_in_submap (submap &current_submap, const tripoint &gridp)
 
void process_items_in_vehicles (submap &current_submap)
 
void process_items_in_vehicle (vehicle &cur_veh, submap &current_submap)
 
template<typename Functor >
void function_over (const tripoint &start, const tripoint &end, Functor fun) const
 Runs a functor over given submaps over submaps in the area, getting next submap only when the current one "runs out" rather than every time. More...
 
level_cacheget_cache (int zlev) const
 
pathfinding_cacheget_pathfinding_cache (int zlev) const
 
void saven (const tripoint &grid)
 
void loadn (const tripoint &grid, bool update_vehicles)
 
void loadn (point grid, bool update_vehicles)
 
void actualize (const tripoint &grid)
 Fast forward a submap that has just been loading into this map. More...
 
void add_roofs (const tripoint &grid)
 Hacks in missing roofs. More...
 
template<typename Container >
void remove_rotten_items (Container &items, const tripoint &p, temperature_flag temperature)
 Go through the list of items, update their rotten status and remove items that have rotten away completely. More...
 
void fill_funnels (const tripoint &p, const time_point &since)
 Try to fill funnel based items here. More...
 
void grow_plant (const tripoint &p)
 Try to grow a harvestable plant to the next stage(s). More...
 
void restock_fruits (const tripoint &p, const time_duration &time_since_last_actualize)
 Try to grow fruits on static plants (not planted by the player) More...
 
void produce_sap (const tripoint &p, const time_duration &time_since_last_actualize)
 Produce sap on tapped maple trees. More...
 
void rad_scorch (const tripoint &p, const time_duration &time_since_last_actualize)
 Radiation-related plant (and fungus?) death. More...
 
void decay_cosmetic_fields (const tripoint &p, const time_duration &time_since_last_actualize)
 
void player_in_field (player &u)
 
void monster_in_field (monster &z)
 
void shift_traps (const tripoint &shift)
 As part of the map shifting, this shifts the trap locations stored in traplocs. More...
 
void copy_grid (const tripoint &to, const tripoint &from)
 
void draw_map (mapgendata &dat)
 
void draw_office_tower (mapgendata &dat)
 
void draw_lab (mapgendata &dat)
 
void draw_temple (mapgendata &dat)
 
void draw_mine (mapgendata &dat)
 
void draw_anthill (mapgendata &dat)
 
void draw_slimepit (mapgendata &dat)
 
void draw_triffid (mapgendata &dat)
 
void draw_connections (mapgendata &dat)
 
bool build_transparency_cache (int zlev)
 
bool build_vision_transparency_cache (const Character &player)
 
void build_sunlight_cache (int pzlev)
 
void generate_lightmap (int zlev)
 
void build_seen_cache (const tripoint &origin, int target_z)
 Calculates the Field Of View for the provided map from the given x, y coordinates. More...
 
void apply_character_light (Character &p)
 
void apply_vision_transparency_cache (const tripoint &center, int target_z, float(&vision_restore_cache)[9], bool(&blocked_restore_cache)[8])
 
void restore_vision_transparency_cache (const tripoint &center, int target_z, float(&vision_restore_cache)[9], bool(&blocked_restore_cache)[8])
 
void set_abs_sub (const tripoint &p)
 Sets abs_sub, see there. More...
 
size_t get_nonant (const tripoint &gridp) const
 Get the index of a submap pointer in the grid given by grid coordinates. More...
 
size_t get_nonant (point gridp) const
 
void setsubmap (size_t grididx, submap *smap)
 Set the submap pointer in grid at the give index. More...
 

Detailed Description

Manage and cache data about a part of the map.

Despite the name, this class isn't actually responsible for managing the map as a whole. For that function, see mapbuffer. Instead, this class loads a part of the mapbuffer into a cache, and adds certain temporary information such as lighting calculations to it.

To understand the following descriptions better, you should also read Map Management

The map coordinates always start at (0, 0) for the top-left and end at (map_width-1, map_height-1) for the bottom-right.

The actual map data is stored in submap instances. These instances are managed by mapbuffer. References to the currently active submaps are stored in map::grid: 0 1 2 3 4 5 6 7 8 In this example, the top-right submap would be at grid[2].

When the player moves between submaps, the whole map is shifted, so that if the player moves one submap to the right, (0, 0) now points to a tile one submap to the right from before

Definition at line 383 of file map.h.

Member Enumeration Documentation

◆ iteration_state

enum map::iteration_state
private

Enum used by functors in function_over to control execution.

Enumerator
ITER_CONTINUE 
ITER_SKIP_SUBMAP 
ITER_SKIP_ZLEVEL 
ITER_FINISH 

Definition at line 1916 of file map.h.

1916 {
1917 ITER_CONTINUE = 0, // Keep iterating
1918 ITER_SKIP_SUBMAP, // Skip the rest of this submap
1919 ITER_SKIP_ZLEVEL, // Skip the rest of this z-level
1920 ITER_FINISH // End iteration
1921 };
@ ITER_SKIP_ZLEVEL
Definition: map.h:1919
@ ITER_SKIP_SUBMAP
Definition: map.h:1918
@ ITER_CONTINUE
Definition: map.h:1917
@ ITER_FINISH
Definition: map.h:1920

Constructor & Destructor Documentation

◆ map() [1/2]

map::map ( int  mapsize = MAPSIZE,
bool  zlev = false 
)

Definition at line 174 of file map.cpp.

175{
176 my_MAPSIZE = mapsize;
177 zlevels = zlev;
178 if( zlevels ) {
179 grid.resize( static_cast<size_t>( my_MAPSIZE * my_MAPSIZE * OVERMAP_LAYERS ), nullptr );
180 } else {
181 grid.resize( static_cast<size_t>( my_MAPSIZE * my_MAPSIZE ), nullptr );
182 }
183
184 for( auto &ptr : caches ) {
185 ptr = std::make_unique<level_cache>();
186 }
187
188 for( auto &ptr : pathfinding_caches ) {
189 ptr = std::make_unique<pathfinding_cache>();
190 }
191
192 dbg( DL::Info ) << "map::map(): my_MAPSIZE: " << my_MAPSIZE << " z-levels enabled:" << zlevels;
193 traplocs.resize( trap::count() );
194}
std::vector< std::vector< tripoint > > traplocs
This vector contains an entry for each trap type, it has therefor the same size as the traplist vecto...
Definition: map.h:1948
std::array< std::unique_ptr< pathfinding_cache >, OVERMAP_LAYERS > pathfinding_caches
Definition: map.h:1958
std::vector< submap * > grid
The list of currently loaded submaps.
Definition: map.h:1941
int my_MAPSIZE
Definition: map.h:1769
bool zlevels
Definition: map.h:1770
std::array< std::unique_ptr< level_cache >, OVERMAP_LAYERS > caches
Holds caches for visibility, light, transparency and vehicles.
Definition: map.h:1956
@ Info
Information (default: enabled).
const void * ptr(const T *p)
\rst Converts p to const void* for pointer formatting.
static constexpr int OVERMAP_LAYERS
#define dbg(x)
Definition: map.cpp:138
static size_t count()
Definition: trap.cpp:95

References caches, trap::count(), dbg, grid, Info, my_MAPSIZE, OVERMAP_LAYERS, pathfinding_caches, ptr(), traplocs, and zlevels.

Referenced by check_submap_active_item_consistency().

◆ map() [2/2]

map::map ( bool  zlev)
inlineexplicit

Definition at line 391 of file map.h.

391: map( MAPSIZE, zlev ) { }
map(int mapsize=MAPSIZE, bool zlev=false)
Definition: map.cpp:174
static constexpr int MAPSIZE

◆ ~map()

map::~map ( )
virtualdefault

Member Function Documentation

◆ access_cache() [1/2]

level_cache & map::access_cache ( int  zlev)

Definition at line 8807 of file map.cpp.

8808{
8809 if( zlev >= -OVERMAP_DEPTH && zlev <= OVERMAP_HEIGHT ) {
8810 return *caches[zlev + OVERMAP_DEPTH];
8811 }
8812
8813 debugmsg( "access_cache called with invalid z-level: %d", zlev );
8814 return nullcache;
8815}
#define debugmsg(...)
Debug message of level DL::Error and class DC::DebugMsg, also includes the source file name and line,...
Definition: debug.h:74
static constexpr int OVERMAP_HEIGHT
static constexpr int OVERMAP_DEPTH
static level_cache nullcache
Definition: map.cpp:142

References caches, debugmsg, nullcache, OVERMAP_DEPTH, and OVERMAP_HEIGHT.

Referenced by get_known_connections(), game::place_player_overmap(), process_items(), explosion_handler::shrapnel(), scent_map::update(), and game::vertical_shift().

◆ access_cache() [2/2]

const level_cache & map::access_cache ( int  zlev) const

Definition at line 8817 of file map.cpp.

8818{
8819 if( zlev >= -OVERMAP_DEPTH && zlev <= OVERMAP_HEIGHT ) {
8820 return *caches[zlev + OVERMAP_DEPTH];
8821 }
8822
8823 debugmsg( "access_cache called with invalid z-level: %d", zlev );
8824 return nullcache;
8825}

References caches, debugmsg, nullcache, OVERMAP_DEPTH, and OVERMAP_HEIGHT.

◆ accessible_items()

bool map::accessible_items ( const tripoint t) const

Check whether the player can access the items located .

Certain furniture/terrain may prevent that (e.g. a locked safe).

Definition at line 6629 of file map.cpp.

6630{
6631 return !has_flag( "SEALED", t ) || has_flag( "LIQUIDCONT", t );
6632}
bool has_flag(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2351

References has_flag().

Referenced by basecamp::form_crafting_inventory(), inventory::form_from_map(), player::get_eligible_containers_for_crafting(), has_clear_path_to_pickup_items(), try_fuel_fire(), and use_charges().

◆ actualize()

void map::actualize ( const tripoint grid)
protected

Fast forward a submap that has just been loading into this map.

This is used to rot and remove rotten items, grow plants, fill funnels etc.

Definition at line 7480 of file map.cpp.

7481{
7482 submap *const tmpsub = get_submap_at_grid( grid );
7483 if( tmpsub == nullptr ) {
7484 debugmsg( "Actualize called on null submap (%d,%d,%d)", grid.x, grid.y, grid.z );
7485 return;
7486 }
7487
7488 const time_duration time_since_last_actualize = calendar::turn - tmpsub->last_touched;
7489 const bool do_funnels = ( grid.z >= 0 );
7490
7491 // check spoiled stuff, and fill up funnels while we're at it
7492 for( int x = 0; x < SEEX; x++ ) {
7493 for( int y = 0; y < SEEY; y++ ) {
7494 const tripoint pnt = sm_to_ms_copy( grid ) + point( x, y );
7495 const point p( x, y );
7496 const auto &furn = this->furn( pnt ).obj();
7497 if( furn.has_flag( "EMITTER" ) ) {
7498 field_furn_locs.push_back( pnt );
7499 }
7500 // plants contain a seed item which must not be removed under any circumstances
7501 if( !furn.has_flag( "DONT_REMOVE_ROTTEN" ) ) {
7503 remove_rotten_items( tmpsub->get_items( { x, y } ), pnt, temperature );
7504 }
7505
7506 const auto trap_here = tmpsub->get_trap( p );
7507 if( trap_here != tr_null ) {
7508 traplocs[trap_here.to_i()].push_back( pnt );
7509 }
7510 const ter_t &ter = tmpsub->get_ter( p ).obj();
7511 if( ter.trap != tr_null && ter.trap != tr_ledge ) {
7512 traplocs[ter.trap.to_i()].push_back( pnt );
7513 }
7514
7515 if( do_funnels ) {
7516 fill_funnels( pnt, tmpsub->last_touched );
7517 }
7518
7519 grow_plant( pnt );
7520
7521 restock_fruits( pnt, time_since_last_actualize );
7522
7523 produce_sap( pnt, time_since_last_actualize );
7524
7525 rad_scorch( pnt, time_since_last_actualize );
7526
7527 decay_cosmetic_fields( pnt, time_since_last_actualize );
7528 }
7529 }
7530
7531 // the last time we touched the submap, is right now.
7532 tmpsub->last_touched = calendar::turn;
7533}
const T & obj() const
Definition: ammo_effect.cpp:26
int to_i() const
Returns the identifier as plain int.
Definition: int_id.h:84
void rad_scorch(const tripoint &p, const time_duration &time_since_last_actualize)
Radiation-related plant (and fungus?) death.
Definition: map.cpp:7414
void fill_funnels(const tripoint &p, const time_point &since)
Try to fill funnel based items here.
Definition: map.cpp:7202
submap * get_submap_at_grid(point gridp) const
Get submap pointer in the grid at given grid coordinates.
Definition: map.h:1819
void remove_rotten_items(Container &items, const tripoint &p, temperature_flag temperature)
Go through the list of items, update their rotten status and remove items that have rotten away compl...
Definition: map.cpp:7163
std::vector< tripoint > field_furn_locs
Vector of tripoints containing active field-emitting furniture.
Definition: map.h:1952
void decay_cosmetic_fields(const tripoint &p, const time_duration &time_since_last_actualize)
Definition: map.cpp:7460
void restock_fruits(const tripoint &p, const time_duration &time_since_last_actualize)
Try to grow fruits on static plants (not planted by the player)
Definition: map.cpp:7303
ter_id ter(const tripoint &p) const
Definition: map.cpp:1556
void grow_plant(const tripoint &p)
Try to grow a harvestable plant to the next stage(s).
Definition: map.cpp:7225
void produce_sap(const tripoint &p, const time_duration &time_since_last_actualize)
Produce sap on tapped maple trees.
Definition: map.cpp:7317
furn_id furn(const tripoint &p) const
Definition: map.cpp:1406
Definition: submap.h:65
time_point last_touched
Definition: submap.h:211
trap_id get_trap(point p) const
Definition: submap.h:73
ter_id get_ter(point p) const
Definition: submap.h:99
cata::colony< item > & get_items(point p)
Definition: submap.h:140
A duration defined as a number of specific time units.
Definition: calendar.h:180
point sm_to_ms_copy(point p)
temperature_flag
Definition: enums.h:42
static constexpr int SEEX
static constexpr int SEEY
static temperature_flag temperature_flag_at_point(const map &m, const tripoint &p)
Definition: map.cpp:4667
static const trap_str_id tr_ledge("tr_ledge")
time_point turn
Definition: calendar.cpp:36
quantity< int, temperature_in_millidegree_celsius_tag > temperature
Definition: point.h:35
Definition: mapdata.h:461
trap_id tr_null
Definition: trap.cpp:276

References debugmsg, decay_cosmetic_fields(), field_furn_locs, fill_funnels(), furn(), submap::get_items(), get_submap_at_grid(), submap::get_ter(), submap::get_trap(), grid, grow_plant(), submap::last_touched, int_id< T >::obj(), produce_sap(), rad_scorch(), remove_rotten_items(), restock_fruits(), SEEX, SEEY, sm_to_ms_copy(), temperature_flag_at_point(), ter(), int_id< T >::to_i(), tr_ledge, tr_null, traplocs, and calendar::turn.

Referenced by loadn().

◆ add_camp()

void map::add_camp ( const tripoint_abs_omt omt_pos,
const std::string &  name 
)

Definition at line 5652 of file map.cpp.

5653{
5654 basecamp temp_camp = basecamp( name, omt_pos );
5655 overmap_buffer.add_camp( temp_camp );
5656 g->u.camps.insert( omt_pos );
5657 g->validate_camps();
5658}
std::string name(const tripoint &p)
Definition: map.cpp:1383
void add_camp(const basecamp &camp)
Add Basecamp to overmapbuffer.
std::unique_ptr< game > g
Definition: game.cpp:281
overmapbuffer overmap_buffer

References overmapbuffer::add_camp(), g, name(), and overmap_buffer.

Referenced by get_basecamp().

◆ add_computer()

computer * map::add_computer ( const tripoint p,
const std::string &  name,
int  security 
)

Definition at line 5820 of file mapgen.cpp.

5821{
5822 // TODO: Turn this off?
5823 ter_set( p, t_console );
5824 point l;
5825 submap *const place_on_submap = get_submap_at( p, l );
5826 place_on_submap->set_computer( l, computer( name, security ) );
5827 return place_on_submap->get_computer( l );
5828}
bool ter_set(const tripoint &p, const ter_id &new_terrain)
Definition: map.cpp:1697
submap * get_submap_at(const tripoint &p) const
Get the submap pointer containing the specified position within the reality bubble.
Definition: map.cpp:8376
void set_computer(point p, const computer &c)
Definition: submap.cpp:238
const computer * get_computer(point p) const
Definition: submap.cpp:212
ter_id t_console
Definition: mapdata.cpp:706

References submap::get_computer(), get_submap_at(), name(), submap::set_computer(), t_console, and ter_set().

Referenced by jmapgen_computer::apply(), create_lab_consoles(), draw_lab(), mission_start::place_npc_software(), and science_room().

◆ add_corpse()

void map::add_corpse ( const tripoint p)

Definition at line 8520 of file map.cpp.

8521{
8522 item body;
8523
8524 const bool isReviveSpecial = one_in( 10 );
8525
8526 if( !isReviveSpecial ) {
8527 body = item::make_corpse();
8528 } else {
8529 body = item::make_corpse( mon_zombie );
8530 body.set_flag( "REVIVE_SPECIAL" );
8531 }
8532
8533 put_items_from_loc( item_group_id( "default_zombie_clothes" ), p );
8534 if( one_in( 3 ) ) {
8535 put_items_from_loc( item_group_id( "default_zombie_items" ), p );
8536 }
8537
8538 add_item_or_charges( p, body );
8539}
Definition: item.h:211
static item make_corpse(const mtype_id &mt=string_id< mtype >::NULL_ID(), time_point turn=calendar::turn, const std::string &name="", int upgrade_time=-1)
Make a corpse of the given monster type.
Definition: item.cpp:507
item & set_flag(const std::string &flag)
Idempotent filter setting an item specific flag.
Definition: item.cpp:5332
item & add_item_or_charges(const tripoint &pos, item obj, bool overflow=true)
Adds an item to map tile or stacks charges.
Definition: map.cpp:4294
std::vector< item * > put_items_from_loc(const item_group_id &loc, const tripoint &p, const time_point &turn=calendar::start_of_cataclysm)
Place items from an item group at p.
Definition: mapgen.cpp:5608
static const mtype_id mon_zombie("mon_zombie")
bool one_in(int chance)
Definition: rng.cpp:65
string_id< Item_group > item_group_id
Definition: type_id.h:77

References add_item_or_charges(), item::make_corpse(), mon_zombie, one_in(), put_items_from_loc(), and item::set_flag().

Referenced by add_corpse(), MapExtras::mx_looters(), MapExtras::mx_mayhem(), and MapExtras::mx_minefield().

◆ add_field()

bool map::add_field ( const tripoint p,
const field_type_id type_id,
int  intensity = INT_MAX,
const time_duration age = 0_turns,
bool  hit_player = true 
)

Add field entry at point, or set intensity if present.

Returns
false if the field could not be created (out of bounds), otherwise true.

Definition at line 5469 of file map.cpp.

5471{
5472 if( !inbounds( p ) ) {
5473 return false;
5474 }
5475
5476 if( !type_id ) {
5477 debugmsg( "Tried to add null field" );
5478 return false;
5479 }
5480
5481 const field_type &fd_type = *type_id;
5482 intensity = std::min( intensity, fd_type.get_max_intensity() );
5483 if( intensity <= 0 ) {
5484 return false;
5485 }
5486
5487 point l;
5488 submap *const current_submap = get_submap_at( p, l );
5489 current_submap->is_uniform = false;
5491
5492 if( current_submap->get_field( l ).add_field( type_id, intensity, age ) ) {
5493 //Only adding it to the count if it doesn't exist.
5494 if( !current_submap->field_count++ ) {
5495 get_cache( p.z ).field_cache.set( static_cast<size_t>( p.x / SEEX + ( (
5496 p.y / SEEX ) * MAPSIZE ) ) );
5497 }
5498 }
5499
5500 if( hit_player ) {
5501 Character &player_character = get_player_character();
5502 if( g != nullptr && this == &get_map() && p == player_character.pos() ) {
5503 //Hit the player with the field if it spawned on top of them.
5504 creature_in_field( player_character );
5505 }
5506 }
5507
5508 // Dirty the transparency cache now that field processing doesn't always do it
5509 if( fd_type.dirty_transparency_cache || !fd_type.is_transparent() ) {
5512 }
5513
5514 if( fd_type.is_dangerous() ) {
5516 }
5517
5518 // Ensure blood type fields don't hang in the air
5519 if( zlevels && fd_type.accelerated_decay ) {
5520 support_dirty( p );
5521 }
5522
5523 return true;
5524}
Character & get_player_character()
Definition: character.cpp:393
const tripoint & pos() const override
Definition: character.cpp:587
bool add_field(const field_type_id &field_type_to_add, int new_intensity=1, const time_duration &new_age=0_turns)
Inserts the given field_type_id into the field list for a given tile if it does not already exist.
Definition: field.cpp:190
void set_transparency_cache_dirty(const int zlev)
Sets a dirty flag on the a given cache.
Definition: map.cpp:199
level_cache & get_cache(int zlev) const
Definition: map.h:1976
virtual bool inbounds(const tripoint &p) const
Definition: map.cpp:7831
void set_pathfinding_cache_dirty(int zlev)
Definition: map.cpp:8862
void creature_in_field(Creature &critter)
Apply field effects to the creature when it's on a square with fields.
Definition: map_field.cpp:1563
void support_dirty(const tripoint &p)
Definition: map.cpp:2325
void invalidate_max_populated_zlev(int zlev)
Conditionally invalidates max_pupulated_zlev cache if the submap uniformity change occurs above curre...
Definition: map.cpp:9093
void set_seen_cache_dirty(const tripoint change_location)
Definition: map.cpp:206
field & get_field(point p)
Definition: submap.h:149
int field_count
Definition: submap.h:210
bool is_uniform
Definition: submap.h:204
map & get_map()
Definition: map.cpp:146
bool accelerated_decay
Definition: field_type.h:179
bool is_transparent() const
Definition: field_type.h:262
bool dirty_transparency_cache
Definition: field_type.h:161
bool is_dangerous() const
Definition: field_type.h:256
int get_max_intensity() const
Definition: field_type.h:268
std::bitset< MAPSIZE *MAPSIZE > field_cache
Definition: map.h:352
int y
Definition: point.h:137
int z
Definition: point.h:138
int x
Definition: point.h:136

References field_type::accelerated_decay, field::add_field(), creature_in_field(), debugmsg, field_type::dirty_transparency_cache, level_cache::field_cache, submap::field_count, g, get_cache(), submap::get_field(), get_map(), field_type::get_max_intensity(), get_player_character(), get_submap_at(), inbounds(), invalidate_max_populated_zlev(), field_type::is_dangerous(), field_type::is_transparent(), submap::is_uniform, MAPSIZE, Character::pos(), SEEX, set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_transparency_cache_dirty(), support_dirty(), tripoint::x, tripoint::y, tripoint::z, and zlevels.

Referenced by Character::activate_bionic(), jmapgen_field::apply(), apply_ammo_effects(), Character::blossoms(), mattack::boomer(), mattack::boomer_glow(), start_location::burn(), create_anomaly(), spell::create_field(), create_hot_air(), explosion_handler::do_blast(), draw_lab(), draw_mine(), draw_temple(), draw_triffid(), drop_fields(), editmap::edit_fld(), iexamine::fireplace(), mattack::flame(), gas_spread_to(), hit_with_fire(), madd_field(), MapExtras::mx_casings(), MapExtras::mx_corpses(), MapExtras::mx_drugdeal(), MapExtras::mx_looters(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), MapExtras::mx_portal_in(), MapExtras::mx_roadblock(), MapExtras::mx_spider(), game::process_artifact(), process_fields_in_submap(), item::process_litcig(), explosion_handler::explosion_funcs::resonance_cascade(), mattack::riotbot(), set_field_intensity(), shoot(), Character::suffer_from_other_mutations(), explosion_iuse::trigger_explosion(), and consume_drug_iuse::use().

◆ add_item() [1/2]

item & map::add_item ( const tripoint p,
item  new_item 
)

Place an item on the map, despite the parameter name, this is not necessarily a new item.

WARNING: does -not- check volume or stack charges. player functions (drop etc) should use map::add_item_or_charges

Returns
The item that got added, or nulitem.

Definition at line 4394 of file map.cpp.

4395{
4396 if( !inbounds( p ) ) {
4397 return null_item_reference();
4398 }
4399 point l;
4400 submap *const current_submap = get_submap_at( p, l );
4401
4402 // Process foods when they are added to the map, here instead of add_item_at()
4403 // to avoid double processing food and corpses during active item processing.
4404 if( new_item.is_food() ) {
4405 new_item.process( nullptr, p, false );
4406 }
4407
4408 if( new_item.made_of( LIQUID ) && has_flag( "SWIMMABLE", p ) ) {
4409 return null_item_reference();
4410 }
4411
4412 if( has_flag( "DESTROY_ITEM", p ) ) {
4413 return null_item_reference();
4414 }
4415
4416 if( new_item.has_flag( "ACT_IN_FIRE" ) && get_field( p, fd_fire ) != nullptr ) {
4417 if( new_item.has_flag( "BOMB" ) && new_item.is_transformable() ) {
4418 //Convert a bomb item into its transformable version, e.g. incendiary grenade -> active incendiary grenade
4419 new_item.convert( dynamic_cast<const iuse_transform *>
4420 ( new_item.type->get_use( "transform" )->get_actor_ptr() )->target );
4421 }
4422 new_item.active = true;
4423 }
4424
4425 if( new_item.is_map() && !new_item.has_var( "reveal_map_center_omt" ) ) {
4426 new_item.set_var( "reveal_map_center_omt", ms_to_omt_copy( getabs( p ) ) );
4427 }
4428
4429 current_submap->is_uniform = false;
4431
4432 current_submap->update_lum_add( l, new_item );
4433
4434 const map_stack::iterator new_pos = current_submap->get_items( l ).insert( new_item );
4435 if( new_item.needs_processing() ) {
4436 if( current_submap->active_items.empty() ) {
4437 submaps_with_active_items.insert( tripoint( abs_sub.x + p.x / SEEX, abs_sub.y + p.y / SEEY, p.z ) );
4438 }
4439 current_submap->active_items.add( *new_pos, l );
4440 }
4441
4442 return *new_pos;
4443}
void add(item &it, point location)
Adds the reference to the cache.
bool empty() const
Returns true if the cache is empty.
bool is_transformable() const
Definition: item.cpp:6958
bool process(player *carrier, const tripoint &pos, bool activate, temperature_flag flag=temperature_flag::TEMP_NORMAL)
This is called once each turn.
Definition: item.cpp:9586
bool needs_processing() const
Whether the item should be processed (by calling process).
Definition: item.cpp:8930
bool active
Definition: item.h:2234
const std::vector< material_id > & made_of() const
The ids of all the materials this is made of.
Definition: item.cpp:6413
item & convert(const itype_id &new_type)
Filter converting this instance to another type preserving all other aspects.
Definition: item.cpp:533
bool has_var(const std::string &name) const
Whether the variable is defined at all.
Definition: item.cpp:1075
void set_var(const std::string &name, int value)
Definition: item.cpp:1000
bool has_flag(const std::string &flag) const
Definition: item.cpp:5303
bool is_map() const
Definition: item.cpp:6714
bool is_food() const
Definition: item.cpp:6592
const itype * type
Definition: item.h:2157
Transform an item into a specific type.
Definition: iuse_actor.h:52
itype_id target
type of the resulting item
Definition: iuse_actor.h:58
std::set< tripoint > submaps_with_active_items
Set of submaps that contain active items in absolute coordinates.
Definition: map.h:1962
field_entry * get_field(const tripoint &p, const field_type_id &type)
Get field of specific type at point.
Definition: map.cpp:5446
tripoint getabs(const tripoint &p) const
Translates local (to this map) coordinates of a square to global absolute coordinates.
Definition: map.cpp:8335
tripoint abs_sub
Absolute coordinates of first submap (get_submap_at(0,0)) This is in submap coordinates (see overmapb...
Definition: map.h:1784
void update_lum_add(point p, const item &i)
Definition: submap.h:130
active_item_cache active_items
Definition: submap.h:208
point ms_to_omt_copy(point p)
@ LIQUID
Definition: enums.h:175
field_type_id fd_fire
Definition: field_type.cpp:345
item & null_item_reference()
Returns a reference to a null item (see item::is_null).
Definition: item.cpp:322
const use_function * get_use(const std::string &iuse_name) const
Definition: itype.cpp:166
iuse_actor * get_actor_ptr()
Definition: iuse.h:315

References abs_sub, item::active, submap::active_items, active_item_cache::add(), item::convert(), active_item_cache::empty(), fd_fire, use_function::get_actor_ptr(), get_field(), submap::get_items(), get_submap_at(), itype::get_use(), getabs(), item::has_flag(), has_flag(), item::has_var(), inbounds(), invalidate_max_populated_zlev(), item::is_food(), item::is_map(), item::is_transformable(), submap::is_uniform, LIQUID, item::made_of(), ms_to_omt_copy(), item::needs_processing(), null_item_reference(), item::process(), SEEX, SEEY, item::set_var(), submaps_with_active_items, iuse_transform::target, item::type, submap::update_lum_add(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by add_item(), add_item_or_charges(), item::ammo_consume(), iexamine::arcfurnace_empty(), iexamine::arcfurnace_full(), draw_mine(), extract_or_wreck_cbms(), iexamine::fvat_empty(), iexamine::fvat_full(), iexamine::keg(), iexamine::kiln_empty(), iexamine::kiln_full(), mill_activate(), mill_load_food(), Character::perform_uninstall(), place_gas_pump(), place_toilet(), iexamine::pour_into_keg(), iexamine::reload_furniture(), smoker_activate(), smoker_load_food(), Character::uninstall_bionic(), and avatar_action::wield().

◆ add_item() [2/2]

void map::add_item ( point  p,
item  new_item 
)
inline

Definition at line 1245 of file map.h.

1245 {
1246 add_item( tripoint( p, abs_sub.z ), new_item );
1247 }
item & add_item(const tripoint &p, item new_item)
Place an item on the map, despite the parameter name, this is not necessarily a new item.
Definition: map.cpp:4394

References abs_sub, add_item(), and tripoint::z.

◆ add_item_or_charges() [1/2]

item & map::add_item_or_charges ( const tripoint pos,
item  obj,
bool  overflow = true 
)

Adds an item to map tile or stacks charges.

Parameters
posWhere to add item
objItem to add
overflowif destination is full attempt to drop on adjacent tiles
Returns
reference to dropped (and possibly stacked) item or null item on failure
Warning
function is relatively expensive and meant for user initiated actions, not mapgen

Definition at line 4294 of file map.cpp.

4295{
4296 // Checks if item would not be destroyed if added to this tile
4297 auto valid_tile = [&]( const tripoint & e ) {
4298 if( !inbounds( e ) ) {
4299 // should never happen
4300 debugmsg( "add_item_or_charges: %s is out of bounds (adding item '%s' [%d])",
4301 e.to_string(), obj.typeId().c_str(), obj.charges );
4302 return false;
4303 }
4304
4305 // Some tiles destroy items (e.g. lava)
4306 if( has_flag( "DESTROY_ITEM", e ) ) {
4307 return false;
4308 }
4309
4310 // Cannot drop liquids into tiles that are comprised of liquid
4311 if( obj.made_of( LIQUID ) && has_flag( "SWIMMABLE", e ) ) {
4312 return false;
4313 }
4314
4315 return true;
4316 };
4317
4318 // Checks if sufficient space at tile to add item
4319 auto valid_limits = [&]( const tripoint & e ) {
4320 return obj.volume() <= free_volume( e ) && i_at( e ).size() < MAX_ITEM_IN_SQUARE;
4321 };
4322
4323 // Performs the actual insertion of the object onto the map
4324 auto place_item = [&]( const tripoint & tile ) -> item& {
4325 if( obj.count_by_charges() )
4326 {
4327 for( auto &e : i_at( tile ) ) {
4328 if( e.merge_charges( obj ) ) {
4329 return e;
4330 }
4331 }
4332 }
4333
4334 support_dirty( tile );
4335 return add_item( tile, obj );
4336 };
4337
4338 // Some items never exist on map as a discrete item (must be contained by another item)
4339 if( obj.has_flag( "NO_DROP" ) ) {
4340 return null_item_reference();
4341 }
4342
4343 // If intended drop tile destroys the item then we don't attempt to overflow
4344 if( !valid_tile( pos ) ) {
4345 return null_item_reference();
4346 }
4347
4348 if( ( !has_flag( "NOITEM", pos ) || ( has_flag( "LIQUIDCONT", pos ) && obj.made_of( LIQUID ) ) )
4349 && valid_limits( pos ) ) {
4350 // Pass map into on_drop, because this map may not be the global map object (in mapgen, for instance).
4351 if( obj.made_of( LIQUID ) || !obj.has_flag( "DROP_ACTION_ONLY_IF_LIQUID" ) ) {
4352 if( obj.on_drop( pos, *this ) ) {
4353 return null_item_reference();
4354 }
4355
4356 }
4357 // If tile can contain items place here...
4358 return place_item( pos );
4359
4360 } else if( overflow ) {
4361 // ...otherwise try to overflow to adjacent tiles (if permitted)
4362 const int max_dist = 2;
4363 std::vector<tripoint> tiles = closest_points_first( pos, max_dist );
4364 tiles.erase( tiles.begin() ); // we already tried this position
4365 const int max_path_length = 4 * max_dist;
4366 const pathfinding_settings setting( 0, max_dist, max_path_length, 0, false, true, false, false,
4367 false );
4368 for( const tripoint &e : tiles ) {
4369 if( !inbounds( e ) ) {
4370 continue;
4371 }
4372 //must be a path to the target tile
4373 if( route( pos, e, setting ).empty() ) {
4374 continue;
4375 }
4376 if( obj.made_of( LIQUID ) || !obj.has_flag( "DROP_ACTION_ONLY_IF_LIQUID" ) ) {
4377 if( obj.on_drop( e, *this ) ) {
4378 return null_item_reference();
4379 }
4380 }
4381
4382 if( !valid_tile( e ) || !valid_limits( e ) ||
4383 has_flag( "NOITEM", e ) || has_flag( "SEALED", e ) ) {
4384 continue;
4385 }
4386 return place_item( e );
4387 }
4388 }
4389
4390 // failed due to lack of space at target tile (+/- overflow tiles)
4391 return null_item_reference();
4392}
size_t size() const
Definition: item_stack.cpp:10
bool count_by_charges() const
Definition: item.cpp:6005
units::volume volume(bool integral=false) const
Total volume of an item accounting for all contained/integrated items NOTE: Result is rounded up to n...
Definition: item.cpp:5104
int charges
Definition: item.h:2196
bool on_drop(const tripoint &pos)
Invokes item type's itype::drop_action.
Definition: item.cpp:9982
const itype_id & typeId() const
return the unique identifier of the items underlying type
Definition: item.cpp:8353
map_stack i_at(const tripoint &p)
Definition: map.cpp:4149
units::volume free_volume(const tripoint &p)
Definition: map.cpp:4289
std::vector< tripoint > route(const tripoint &f, const tripoint &t, const pathfinding_settings &settings, const std::set< tripoint > &pre_closed={{ }}) const
Calculate the best path using A*.
const char * c_str() const
Interface to the plain C-string of the id.
Definition: string_id.h:247
std::vector< coords::coord_point< Point, Origin, Scale > > closest_points_first(const coords::coord_point< Point, Origin, Scale > &loc, int min_dist, int max_dist)
Definition: coordinates.h:596
static constexpr int MAX_ITEM_IN_SQUARE

References add_item(), string_id< T >::c_str(), item::charges, closest_points_first(), item::count_by_charges(), debugmsg, free_volume(), item::has_flag(), has_flag(), i_at(), inbounds(), LIQUID, item::made_of(), MAX_ITEM_IN_SQUARE, null_item_reference(), item::on_drop(), wrapped_vehicle::pos, route(), item_stack::size(), support_dirty(), item::typeId(), and item::volume().

Referenced by Character::absorb_hit(), computer_session::action_conveyor(), computer_session::action_data_anal(), computer_session::action_sample(), Character::activate_bionic(), add_corpse(), MapgenRemovePartHandler::add_item_or_charges(), add_item_or_charges(), jmapgen_liquid_item::apply(), butchery_drops_harvest(), butchery_quarter(), defense_game::caravan(), game::catch_a_monster(), activity_handlers::chop_logs_finish(), doors::close_door(), talk_function::companion_return(), complete_construction(), cycle_action(), vehicle::damage_direct(), monexamine::deactivate_pet(), iexamine::deployed_furniture(), game::disable_robot(), basecamp::distribute_food(), draw_lab(), Character::drop_invalid_inventory(), drop_items(), npc::drop_items(), drop_on_map(), drop_or_embed_projectile(), talk_function::drop_stolen_item(), talk_function::drop_weapon(), monexamine::dump_items(), iexamine::elevator(), explosion_handler::emp_blast(), farm_action(), fetch_activity(), talk_function::field_plant(), activity_handlers::fill_liquid_do_turn(), iexamine::fireplace(), game::forced_door_closing(), fromPumpFuel(), iexamine::fvat_full(), iexamine::gaspump(), handle_harvest(), pickup::handle_spillable_contents(), iexamine::harvest_plant(), Character::i_add_or_drop(), map_stack::insert(), make_mon_corpse(), make_rubble(), mill_activate(), move_item(), MapExtras::mx_grave(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), iexamine::nanofab(), om_set_hide_site(), liquid_handler::perform_liquid_transfer(), iexamine::pit_covered(), Character::place_corpse(), basecamp::place_results(), activity_handlers::plant_seed_finish(), talk_function::player_weapon_drop(), iexamine::portable_structure(), process_fields_in_submap(), item::process_litcig(), put_into_vehicle(), iexamine::quern_examine(), rcdrive(), monexamine::remove_armor(), monexamine::remove_bag_from(), monexamine::remove_battery(), rod_fish(), scatter_chunks(), set_item_map(), activity_handlers::shear_finish(), smash_items(), smoker_activate(), iexamine::smoker_options(), spawn_an_item(), spawn_artifact(), spawn_items(), spawn_natural_artifact(), item::spill_contents(), item_contents::spill_contents(), mdeath::splatter(), stash_on_pet(), iexamine::toPumpFuel(), iexamine::trap(), iexamine::tree_maple(), iexamine::tree_maple_tapped(), unroll_digging(), and unpack_actor::use().

◆ add_item_or_charges() [2/2]

item & map::add_item_or_charges ( point  p,
item  obj,
bool  overflow = true 
)
inline

Definition at line 1233 of file map.h.

1233 {
1234 return add_item_or_charges( tripoint( p, abs_sub.z ), obj, overflow );
1235 }

References abs_sub, add_item_or_charges(), and tripoint::z.

◆ add_light_from_items()

void map::add_light_from_items ( const tripoint p,
item_stack::iterator  begin,
item_stack::iterator  end 
)
private

Definition at line 64 of file lightmap.cpp.

66{
67 for( auto itm_it = begin; itm_it != end; ++itm_it ) {
68 float ilum = 0.0f; // brightness
69 units::angle iwidth = 0_degrees; // 0-360 degrees. 0 is a circular light_source
70 units::angle idir = 0_degrees; // otherwise, it's a light_arc pointed in this direction
71 if( itm_it->getlight( ilum, iwidth, idir ) ) {
72 if( iwidth > 0_degrees ) {
73 apply_light_arc( p, idir, ilum, iwidth );
74 } else {
75 add_light_source( p, ilum );
76 }
77 }
78 }
79}
void apply_light_arc(const tripoint &p, units::angle, float luminance, units::angle wideangle=30_degrees)
Definition: lightmap.cpp:1664
void add_light_source(const tripoint &p, float luminance)
Definition: lightmap.cpp:613

References add_light_source(), and apply_light_arc().

Referenced by generate_lightmap().

◆ add_light_source()

void map::add_light_source ( const tripoint p,
float  luminance 
)
private

Definition at line 613 of file lightmap.cpp.

614{
615 auto &light_source_buffer = get_cache( p.z ).light_source_buffer;
616 light_source_buffer[p.x][p.y] = std::max( luminance, light_source_buffer[p.x][p.y] );
617}
float light_source_buffer[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:318

References get_cache(), level_cache::light_source_buffer, tripoint::x, tripoint::y, and tripoint::z.

Referenced by add_light_from_items(), and generate_lightmap().

◆ add_roofs()

void map::add_roofs ( const tripoint grid)
protected

Hacks in missing roofs.

Should be removed when 3D mapgen is done.

Definition at line 7535 of file map.cpp.

7536{
7537 if( !zlevels ) {
7538 // No roofs required!
7539 // Why not? Because submaps below and above don't exist yet
7540 return;
7541 }
7542
7543 submap *const sub_here = get_submap_at_grid( grid );
7544 if( sub_here == nullptr ) {
7545 debugmsg( "Tried to add roofs/floors on null submap on %d,%d,%d",
7546 grid.x, grid.y, grid.z );
7547 return;
7548 }
7549
7550 bool check_roof = grid.z > -OVERMAP_DEPTH;
7551
7552 submap *const sub_below = check_roof ? get_submap_at_grid( grid + tripoint_below ) : nullptr;
7553
7554 if( check_roof && sub_below == nullptr ) {
7555 debugmsg( "Tried to add roofs to sm at %d,%d,%d, but sm below doesn't exist",
7556 grid.x, grid.y, grid.z );
7557 return;
7558 }
7559
7560 for( int x = 0; x < SEEX; x++ ) {
7561 for( int y = 0; y < SEEY; y++ ) {
7562 const ter_id ter_here = sub_here->get_ter( { x, y } );
7563 if( ter_here != t_open_air ) {
7564 continue;
7565 }
7566
7567 if( !check_roof ) {
7568 // Make sure we don't have open air at lowest z-level
7569 sub_here->set_ter( { x, y }, t_rock_floor );
7570 continue;
7571 }
7572
7573 const ter_t &ter_below = sub_below->get_ter( { x, y } ).obj();
7574 if( ter_below.roof ) {
7575 // TODO: Make roof variable a ter_id to speed this up
7576 sub_here->set_ter( { x, y }, ter_below.roof.id() );
7577 }
7578 }
7579 }
7580}
int_id< T > id() const
Translate the string based it to the matching integer based id.
Definition: ammo_effect.cpp:54
void set_ter(point p, ter_id terr)
Definition: submap.h:103
ter_id t_open_air
Definition: mapdata.cpp:729
ter_id t_rock_floor
Definition: mapdata.cpp:629
static constexpr tripoint tripoint_below
Definition: point.h:281
ter_str_id roof
Definition: mapdata.h:471

References debugmsg, get_submap_at_grid(), submap::get_ter(), grid, string_id< T >::id(), OVERMAP_DEPTH, ter_t::roof, SEEX, SEEY, submap::set_ter(), t_open_air, t_rock_floor, tripoint_below, and zlevels.

Referenced by loadn(), and shift().

◆ add_spawn()

void map::add_spawn ( const mtype_id type,
int  count,
const tripoint p,
bool  friendly = false,
int  faction_id = -1,
int  mission_id = -1,
const std::string &  name = "NONE" 
) const

Definition at line 5615 of file mapgen.cpp.

5617{
5618 if( p.x < 0 || p.x >= SEEX * my_MAPSIZE || p.y < 0 || p.y >= SEEY * my_MAPSIZE ) {
5619 debugmsg( "Bad add_spawn(%s, %d, %d, %d)", type.c_str(), count, p.x, p.y );
5620 return;
5621 }
5622 point offset;
5623 submap *place_on_submap = get_submap_at( p, offset );
5624
5625 if( !place_on_submap ) {
5626 debugmsg( "centadodecamonant doesn't exist in grid; within add_spawn(%s, %d, %d, %d, %d)",
5627 type.c_str(), count, p.x, p.y, p.z );
5628 return;
5629 }
5631 return;
5632 }
5633 spawn_point tmp( type, count, offset, faction_id, mission_id, friendly, name );
5634 place_on_submap->spawns.push_back( tmp );
5635}
static bool monster_is_blacklisted(const mtype_id &m)
Definition: mongroup.cpp:280
std::vector< spawn_point > spawns
Definition: submap.h:212
@ type
Definition: enums.h:75
constexpr size_t count()
Definition: fmtlib_core.h:1073

References detail::count(), debugmsg, friendly, get_submap_at(), MonsterGroupManager::monster_is_blacklisted(), my_MAPSIZE, name(), SEEX, SEEY, submap::spawns, type, tripoint::x, tripoint::y, and tripoint::z.

Referenced by jmapgen_monster::apply(), generate(), mission_start::kill_horde_master(), mapgen_ants_generic(), mapgen_ants_larvae(), mapgen_ants_queen(), mapgen_hive(), mapgen_road(), MapExtras::mx_collegekids(), MapExtras::mx_drugdeal(), MapExtras::mx_helicopter(), MapExtras::mx_house_spider(), MapExtras::mx_house_wasp(), MapExtras::mx_jabberwock(), MapExtras::mx_marloss_pilgrimage(), MapExtras::mx_military(), MapExtras::mx_roadblock(), MapExtras::mx_science(), MapExtras::mx_shia(), MapExtras::mx_spider(), mission_start::place_dog(), place_spawns(), mission_start::place_zombie_mom(), process_fields_in_submap(), and rotten_item_spawn().

◆ add_splash()

void map::add_splash ( const field_type_id type,
const tripoint center,
int  radius,
int  intensity 
)

Definition at line 5601 of file map.cpp.

5603{
5604 if( !type.id() ) {
5605 return;
5606 }
5607 // TODO: use Bresenham here and take obstacles into account
5608 for( const tripoint &pnt : points_in_radius( center, radius ) ) {
5609 if( trig_dist( pnt, center ) <= radius && !one_in( intensity ) ) {
5610 add_splatter( type, pnt );
5611 }
5612 }
5613}
tripoint_range< tripoint > points_in_radius(const tripoint &center, size_t radius, size_t radiusz=0) const
Definition: map.cpp:8679
void add_splatter(const field_type_id &type, const tripoint &where, int intensity=1)
Definition: map.cpp:5552
int trig_dist(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:512

References add_splatter(), center, one_in(), points_in_radius(), trig_dist(), and type.

Referenced by smash_items().

◆ add_splatter()

void map::add_splatter ( const field_type_id type,
const tripoint where,
int  intensity = 1 
)

Definition at line 5552 of file map.cpp.

5553{
5554 if( !type.id() || intensity <= 0 ) {
5555 return;
5556 }
5557 if( type.obj().is_splattering ) {
5558 if( const optional_vpart_position vp = veh_at( where ) ) {
5559 vehicle *const veh = &vp->vehicle();
5560 // Might be -1 if all the vehicle's parts at where are marked for removal
5561 const int part = veh->part_displayed_at( vp->mount() );
5562 if( part != -1 ) {
5563 veh->part( part ).blood += 200 * std::min( intensity, 3 ) / 3;
5564 return;
5565 }
5566 }
5567 }
5568 mod_field_intensity( where, type, intensity );
5569}
optional_vpart_position veh_at(const tripoint &p) const
Checks if tile is occupied by vehicle and by which part.
Definition: map.cpp:1067
int mod_field_intensity(const tripoint &p, const field_type_id &type, int offset)
Increment/decrement intensity of field entry at point, creating if not present, removing if intensity...
Definition: map.cpp:5395
Simple wrapper to forward functions that may return a cata::optional to vpart_position.
A vehicle as a whole with all its components.
Definition: vehicle.h:676
int part_displayed_at(point dp) const
Returns which part (as an index into the parts list) is the one that will be displayed for the given ...
Definition: vehicle.cpp:2971
vehicle(const vproto_id &type_id, int init_veh_fuel=-1, int init_veh_status=-1)
Definition: vehicle.cpp:252
vehicle_part & part(int part_num)
Definition: vehicle.cpp:7084
int blood
how much blood covers part (in turns).
Definition: vehicle.h:399

References vehicle_part::blood, mod_field_intensity(), vehicle::part(), vehicle::part_displayed_at(), type, veh_at(), and vehicle::vehicle().

Referenced by add_splash(), add_splatter_trail(), Creature::bleed(), activity_handlers::butcher_finish(), scatter_chunks(), and mdeath::splatter().

◆ add_splatter_trail()

void map::add_splatter_trail ( const field_type_id type,
const tripoint from,
const tripoint to 
)

Definition at line 5571 of file map.cpp.

5573{
5574 if( !type.id() ) {
5575 return;
5576 }
5577 auto trail = line_to( from, to );
5578 int remainder = trail.size();
5579 tripoint last_point = from;
5580 for( tripoint &elem : trail ) {
5581 add_splatter( type, elem );
5582 remainder--;
5583 if( obstructed_by_vehicle_rotation( last_point, elem ) ) {
5584 if( one_in( 2 ) ) {
5585 elem.x = last_point.x;
5586 add_splatter( type, elem, remainder );
5587 } else {
5588 elem.y = last_point.y;
5589 add_splatter( type, elem, remainder );
5590 }
5591 return;
5592 }
5593 if( impassable( elem ) ) { // Blood splatters stop at walls.
5594 add_splatter( type, elem, remainder );
5595 return;
5596 }
5597 last_point = elem;
5598 }
5599}
bool obstructed_by_vehicle_rotation(const tripoint &from, const tripoint &to) const
Checks if a rotated vehicle is blocking diagonal movement, tripoints must be adjacent.
Definition: map.cpp:6556
bool impassable(const tripoint &p) const
Definition: map.cpp:1853
std::vector< coords::coord_point< Point, Origin, Scale > > line_to(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:548

References add_splatter(), impassable(), line_to(), obstructed_by_vehicle_rotation(), one_in(), type, tripoint::x, and tripoint::y.

Referenced by activity_handlers::butcher_finish(), MapExtras::mx_casings(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), projectile_attack(), and activity_handlers::pulp_do_turn().

◆ add_vehicle() [1/4]

vehicle * map::add_vehicle ( const vgroup_id type,
const tripoint p,
units::angle  dir,
int  init_veh_fuel = -1,
int  init_veh_status = -1,
bool  merge_wrecks = true 
)

◆ add_vehicle() [2/4]

vehicle * map::add_vehicle ( const vgroup_id type,
point  p,
units::angle  dir,
int  init_veh_fuel = -1,
int  init_veh_status = -1,
bool  merge_wrecks = true 
)

Definition at line 5643 of file mapgen.cpp.

5645{
5646 return add_vehicle( type.obj().pick(), p, dir, veh_fuel, veh_status, merge_wrecks );
5647}

References add_vehicle(), and type.

◆ add_vehicle() [3/4]

vehicle * map::add_vehicle ( const vproto_id type,
const tripoint p,
units::angle  dir,
int  init_veh_fuel = -1,
int  init_veh_status = -1,
bool  merge_wrecks = true 
)

Definition at line 5655 of file mapgen.cpp.

5657{
5658 if( !type.is_valid() ) {
5659 debugmsg( "Nonexistent vehicle type: \"%s\"", type.c_str() );
5660 return nullptr;
5661 }
5662 if( !inbounds( p ) ) {
5663 dbg( DL::Warn ) << string_format( "Out of bounds add_vehicle t=%s d=%d p=%s",
5664 type, to_degrees( dir ), p.to_string() );
5665 return nullptr;
5666 }
5667
5668 // debugmsg("n=%d x=%d y=%d MAPSIZE=%d ^2=%d", nonant, x, y, MAPSIZE, MAPSIZE*MAPSIZE);
5669 auto veh = std::make_unique<vehicle>( type, veh_fuel, veh_status );
5670 tripoint p_ms = p;
5671 veh->sm_pos = ms_to_sm_remain( p_ms );
5672 veh->pos = p_ms.xy();
5673 veh->place_spawn_items();
5674 // for backwards compatibility, we always spawn with a pivot point of (0,0) so
5675 // that the mount at (0,0) is located at the spawn position.
5676 veh->set_facing_and_pivot( dir, point_zero, false );
5677 //debugmsg("adding veh: %d, sm: %d,%d,%d, pos: %d, %d", veh, veh->smx, veh->smy, veh->smz, veh->posx, veh->posy);
5678 std::unique_ptr<vehicle> placed_vehicle_up =
5679 add_vehicle_to_map( std::move( veh ), merge_wrecks );
5680 vehicle *placed_vehicle = placed_vehicle_up.get();
5681
5682 if( placed_vehicle != nullptr ) {
5683 submap *place_on_submap = get_submap_at_grid( placed_vehicle->sm_pos );
5684 place_on_submap->vehicles.push_back( std::move( placed_vehicle_up ) );
5685 place_on_submap->is_uniform = false;
5687
5688 auto &ch = get_cache( placed_vehicle->sm_pos.z );
5689 ch.vehicle_list.insert( placed_vehicle );
5690 add_vehicle_to_cache( placed_vehicle );
5691
5692 //debugmsg ("grid[%d]->vehicles.size=%d veh.parts.size=%d", nonant, grid[nonant]->vehicles.size(),veh.parts.size());
5693 }
5694 return placed_vehicle;
5695}
std::unique_ptr< vehicle > add_vehicle_to_map(std::unique_ptr< vehicle > veh, bool merge_wrecks)
Takes a vehicle already created with new and attempts to place it on the map, checking for collisions...
Definition: mapgen.cpp:5706
void add_vehicle_to_cache(vehicle *)
Definition: map.cpp:329
std::vector< std::unique_ptr< vehicle > > vehicles
Vehicles on this submap (their (0,0) point is on this submap).
Definition: submap.h:218
tripoint sm_pos
Submap coordinates of the currently loaded submap (see game::m) that contains this vehicle.
Definition: vehicle.h:1926
point ms_to_sm_remain(int &x, int &y)
@ Warn
Warning (default: enabled).
#define dbg(x)
Definition: mapgen.cpp:99
bool move(avatar &you, map &m, const tripoint &d)
constexpr double to_degrees(const units::angle v)
Definition: units_angle.h:36
static constexpr point point_zero
Definition: point.h:260
std::string string_format(std::string_view format, Args &&...args)
Simple wrapper over string_formatter::parse.
constexpr point xy() const
Definition: point.h:206
std::string to_string() const
Definition: point.cpp:34

References add_vehicle_to_cache(), add_vehicle_to_map(), dbg, debugmsg, get_cache(), get_submap_at_grid(), inbounds(), invalidate_max_populated_zlev(), submap::is_uniform, avatar_action::move(), ms_to_sm_remain(), point_zero, vehicle::sm_pos, string_format(), units::to_degrees(), tripoint::to_string(), type, submap::vehicles, Warn, tripoint::xy(), and tripoint::z.

◆ add_vehicle() [4/4]

vehicle * map::add_vehicle ( const vproto_id type,
point  p,
units::angle  dir,
int  init_veh_fuel = -1,
int  init_veh_status = -1,
bool  merge_wrecks = true 
)

Definition at line 5649 of file mapgen.cpp.

5651{
5652 return add_vehicle( type, tripoint( p, abs_sub.z ), dir, veh_fuel, veh_status, merge_wrecks );
5653}

References abs_sub, add_vehicle(), type, and tripoint::z.

◆ add_vehicle_to_cache()

void map::add_vehicle_to_cache ( vehicle veh)

Definition at line 329 of file map.cpp.

330{
331 if( veh == nullptr ) {
332 debugmsg( "Tried to add null vehicle to cache" );
333 return;
334 }
335
336 // Get parts
337 for( const vpart_reference &vpr : veh->get_all_parts() ) {
338 if( vpr.part().removed ) {
339 continue;
340 }
341 const tripoint p = veh->global_part_pos3( vpr.part() );
342 level_cache &ch = get_cache( p.z );
343 ch.veh_in_active_range = true;
344 ch.veh_cached_parts[p] = std::make_pair( veh, static_cast<int>( vpr.part_index() ) );
345 if( inbounds( p ) ) {
346 ch.veh_exists_at[p.x][p.y] = true;
347 }
348 }
349
351}
bool last_full_vehicle_list_dirty
Definition: map.h:1973
vehicle_part_range get_all_parts() const
Yields a range containing all parts (including broken ones) that can be iterated over.
Definition: vehicle.cpp:7074
tripoint global_part_pos3(const int &index) const
Get the coordinates of the studied part of the vehicle.
Definition: vehicle.cpp:3287
This is a wrapper over a vehicle pointer and a reference to a part of it.
bool veh_in_active_range
Definition: map.h:354
bool veh_exists_at[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:355
std::map< tripoint, std::pair< vehicle *, int > > veh_cached_parts
Definition: map.h:356

References debugmsg, vehicle::get_all_parts(), get_cache(), vehicle::global_part_pos3(), inbounds(), last_full_vehicle_list_dirty, level_cache::veh_cached_parts, level_cache::veh_exists_at, level_cache::veh_in_active_range, tripoint::x, tripoint::y, and tripoint::z.

Referenced by add_vehicle(), veh_interact::complete_vehicle(), displace_vehicle(), construct::done_vehicle(), loadn(), vehicle::part_removal_cleanup(), and reset_vehicle_cache().

◆ add_vehicle_to_map()

std::unique_ptr< vehicle > map::add_vehicle_to_map ( std::unique_ptr< vehicle veh,
bool  merge_wrecks 
)
private

Takes a vehicle already created with new and attempts to place it on the map, checking for collisions.

If the vehicle can't be placed, returns NULL, otherwise returns a pointer to the placed vehicle, which may not necessarily be the one passed in (if wreckage is created by fusing cars).

Parameters
vehThe vehicle to place on the map.
merge_wrecksWhether crashed vehicles become part of each other
Returns
The vehicle that was finally placed.

Definition at line 5706 of file mapgen.cpp.

5708{
5709 //We only want to check once per square, so loop over all structural parts
5710 std::vector<int> frame_indices = veh->all_parts_at_location( "structure" );
5711
5712 //Check for boat type vehicles that should be placeable in deep water
5713 const bool can_float = size( veh->get_avail_parts( "FLOATS" ) ) > 2;
5714
5715 //When hitting a wall, only smash the vehicle once (but walls many times)
5716 bool needs_smashing = false;
5717
5718 veh->attach();
5719 veh->refresh_position();
5720
5721 for( std::vector<int>::const_iterator part = frame_indices.begin();
5722 part != frame_indices.end(); part++ ) {
5723 const auto p = veh->global_part_pos3( *part );
5724
5725 //Don't spawn anything in water
5726 if( has_flag_ter( TFLAG_DEEP_WATER, p ) && !can_float ) {
5727 return nullptr;
5728 }
5729
5730 // Don't spawn shopping carts on top of another vehicle or other obstacle.
5731 if( veh->type == vproto_id( "shopping_cart" ) ) {
5732 if( veh_at( p ) || impassable( p ) ) {
5733 return nullptr;
5734 }
5735 }
5736
5737 //For other vehicles, simulate collisions with (non-shopping cart) stuff
5738 vehicle *const other_veh = veh_pointer_or_null( veh_at( p ) );
5739 if( other_veh != nullptr && other_veh->type != vproto_id( "shopping_cart" ) ) {
5740 if( !merge_wrecks ) {
5741 return nullptr;
5742 }
5743
5744 // Hard wreck-merging limit: 200 tiles
5745 // Merging is slow for big vehicles which lags the mapgen
5746 if( frame_indices.size() + other_veh->all_parts_at_location( "structure" ).size() > 200 ) {
5747 return nullptr;
5748 }
5749
5750 /* There's a vehicle here, so let's fuse them together into wreckage and
5751 * smash them up. It'll look like a nasty collision has occurred.
5752 * Trying to do a local->global->local conversion would be a major
5753 * headache, so instead, let's make another vehicle whose (0, 0) point
5754 * is the (0, 0) of the existing vehicle, convert the coordinates of both
5755 * vehicles into global coordinates, find the distance between them and
5756 * p and then install them that way.
5757 * Create a vehicle with type "null" so it starts out empty. */
5758 auto wreckage = std::make_unique<vehicle>();
5759 wreckage->pos = other_veh->pos;
5760 wreckage->sm_pos = other_veh->sm_pos;
5761
5762 //Where are we on the global scale?
5763 const tripoint global_pos = wreckage->global_pos3();
5764
5765 for( const vpart_reference &vpr : veh->get_all_parts() ) {
5766 const tripoint part_pos = veh->global_part_pos3( vpr.part() ) - global_pos;
5767 // TODO: change mount points to be tripoint
5768 wreckage->install_part( part_pos.xy(), vpr.part() );
5769 }
5770
5771 for( const vpart_reference &vpr : other_veh->get_all_parts() ) {
5772 const tripoint part_pos = other_veh->global_part_pos3( vpr.part() ) - global_pos;
5773 wreckage->install_part( part_pos.xy(), vpr.part() );
5774
5775 }
5776
5777 wreckage->name = _( "Wreckage" );
5778
5779 // Now get rid of the old vehicles
5780 std::unique_ptr<vehicle> old_veh = detach_vehicle( other_veh );
5781 // Failure has happened here when caches are corrupted due to bugs.
5782 // Add an assertion to avoid null-pointer dereference later.
5783 assert( old_veh );
5784
5785 // Try again with the wreckage
5786 std::unique_ptr<vehicle> new_veh = add_vehicle_to_map( std::move( wreckage ), true );
5787 if( new_veh != nullptr ) {
5788 new_veh->smash( *this );
5789 return new_veh;
5790 }
5791
5792 // If adding the wreck failed, we want to restore the vehicle we tried to merge with
5793 add_vehicle_to_map( std::move( old_veh ), false );
5794 return nullptr;
5795
5796 } else if( impassable( p ) ) {
5797 if( !merge_wrecks ) {
5798 return nullptr;
5799 }
5800
5801 // There's a wall or other obstacle here; destroy it
5802 destroy( p, true );
5803
5804 // Some weird terrain, don't place the vehicle
5805 if( impassable( p ) ) {
5806 return nullptr;
5807 }
5808
5809 needs_smashing = true;
5810 }
5811 }
5812
5813 if( needs_smashing ) {
5814 veh->smash( *this );
5815 }
5816
5817 return veh;
5818}
void destroy(const tripoint &p, bool silent=false)
Keeps bashing a square until it can't be bashed anymore.
Definition: map.cpp:3696
std::unique_ptr< vehicle > detach_vehicle(vehicle *veh)
Definition: map.cpp:412
bool has_flag_ter(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2370
point pos
Position of the vehicle inside the submap that contains the vehicle.
Definition: vehicle.h:1941
vproto_id type
Type of the vehicle as it was spawned.
Definition: vehicle.h:1880
std::vector< int > all_parts_at_location(const std::string &location) const
Returns all parts in the vehicle that exist in the given location slot.
Definition: vehicle.cpp:2782
@ TFLAG_DEEP_WATER
Definition: mapdata.h:301
const size_t size
Definition: om_direction.h:27
#define _(msg)
Definition: translations.h:116
vehicle * veh_pointer_or_null(const optional_vpart_position &p)

References _, add_vehicle_to_map(), vehicle::all_parts_at_location(), destroy(), detach_vehicle(), vehicle::get_all_parts(), vehicle::global_part_pos3(), has_flag_ter(), impassable(), avatar_action::move(), vehicle::pos, om_direction::size, vehicle::sm_pos, TFLAG_DEEP_WATER, vehicle::type, veh_at(), veh_pointer_or_null(), and tripoint::xy().

Referenced by add_vehicle(), and add_vehicle_to_map().

◆ adjust_radiation() [1/2]

void map::adjust_radiation ( const tripoint p,
int  delta 
)

Increment the radiation in the given tile by the given delta (decrement it if delta is negative)

Definition at line 4117 of file map.cpp.

4118{
4119 if( !inbounds( p ) ) {
4120 return;
4121 }
4122
4123 point l;
4124 submap *const current_submap = get_submap_at( p, l );
4125
4126 int current_radiation = current_submap->get_radiation( l );
4127 current_submap->set_radiation( l, current_radiation + delta );
4128}
void set_radiation(point p, const int radiation)
Definition: submap.h:116
int get_radiation(point p) const
Definition: submap.h:112

References submap::get_radiation(), get_submap_at(), inbounds(), and submap::set_radiation().

Referenced by computer_session::action_irradiator(), adjust_radiation(), MapExtras::mx_crater(), MapExtras::mx_portal_in(), process_fields_in_submap(), and Character::suffer_from_radiation().

◆ adjust_radiation() [2/2]

void map::adjust_radiation ( point  p,
const int  delta 
)
inline

Definition at line 1161 of file map.h.

1161 {
1162 adjust_radiation( tripoint( p, abs_sub.z ), delta );
1163 }
void adjust_radiation(const tripoint &p, int delta)
Increment the radiation in the given tile by the given delta (decrement it if delta is negative)
Definition: map.cpp:4117

References abs_sub, adjust_radiation(), and tripoint::z.

◆ ambient_light_at()

float map::ambient_light_at ( const tripoint p) const

Definition at line 646 of file lightmap.cpp.

647{
648 if( !inbounds( p ) ) {
649 return 0.0f;
650 }
651
652 return get_cache_ref( p.z ).lm[p.x][p.y].max();
653}
const level_cache & get_cache_ref(int zlev) const
Definition: map.h:1989
float max() const
Definition: shadowcasting.h:45
four_quadrants lm[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:314

References get_cache_ref(), inbounds(), level_cache::lm, four_quadrants::max(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by apply_character_light(), game::print_terrain_info(), and Creature::sees().

◆ apparent_light_at()

lit_level map::apparent_light_at ( const tripoint p,
const visibility_variables cache 
) const

Determine the visible light level for a tile, based on light_at for the tile, vision distance, etc.

Parameters
pThe tile on this map to draw.
cacheCurrently cached visibility parameters

Definition at line 729 of file lightmap.cpp.

730{
731 const int dist = rl_dist( g->u.pos(), p );
732
733 // Clairvoyance overrides everything.
734 if( dist <= cache.u_clairvoyance ) {
735 return lit_level::BRIGHT;
736 }
737 const auto &map_cache = get_cache_ref( p.z );
738 const apparent_light_info a = apparent_light_helper( map_cache, p );
739
740 // Unimpaired range is an override to strictly limit vision range based on various conditions,
741 // but the player can still see light sources.
742 if( dist > g->u.unimpaired_range() ) {
743 if( !a.obstructed && map_cache.sm[p.x][p.y] > 0.0 ) {
745 } else {
746 return lit_level::DARK;
747 }
748 }
749 if( a.obstructed ) {
750 if( a.apparent_light > LIGHT_AMBIENT_LIT ) {
751 if( a.apparent_light > cache.g_light_level ) {
752 // This represents too hazy to see detail,
753 // but enough light getting through to illuminate.
755 } else {
756 // If it's not brighter than the surroundings, it just ends up shadowy.
757 return lit_level::LOW;
758 }
759 } else {
760 return lit_level::BLANK;
761 }
762 }
763 // Then we just search for the light level in descending order.
764 if( a.apparent_light > LIGHT_SOURCE_BRIGHT || map_cache.sm[p.x][p.y] > 0.0 ) {
765 return lit_level::BRIGHT;
766 }
767 if( a.apparent_light > LIGHT_AMBIENT_LIT ) {
768 return lit_level::LIT;
769 }
770 if( a.apparent_light >= cache.vision_threshold ) {
771 return lit_level::LOW;
772 } else {
773 return lit_level::BLANK;
774 }
775}
static apparent_light_info apparent_light_helper(const level_cache &map_cache, const tripoint &p)
Helper function for light claculation; exposed here for map editor.
Definition: lightmap.cpp:667
int rl_dist(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:519
static constexpr float LIGHT_SOURCE_BRIGHT
Definition: lightmap.h:9
static constexpr float LIGHT_AMBIENT_LIT
Definition: lightmap.h:18
constexpr double a
Definition: magic.cpp:1030
float vision_threshold
Definition: map.h:128
int u_clairvoyance
Definition: map.h:127

References a, apparent_light_helper(), BLANK, BRIGHT, BRIGHT_ONLY, DARK, g, visibility_variables::g_light_level, get_cache_ref(), LIGHT_AMBIENT_LIT, LIGHT_SOURCE_BRIGHT, LIT, LOW, rl_dist(), visibility_variables::u_clairvoyance, visibility_variables::vision_threshold, tripoint::x, tripoint::y, and tripoint::z.

Referenced by game::draw_look_around_cursor(), game::print_all_tile_info(), editmap::update_view_with_help(), and update_visibility_cache().

◆ apparent_light_helper()

map::apparent_light_info map::apparent_light_helper ( const level_cache map_cache,
const tripoint p 
)
static

Helper function for light claculation; exposed here for map editor.

Definition at line 667 of file lightmap.cpp.

669{
670 const float vis = std::max( map_cache.seen_cache[p.x][p.y], map_cache.camera_cache[p.x][p.y] );
671 const bool obstructed = vis <= LIGHT_TRANSPARENCY_SOLID + 0.1;
672
673 auto is_opaque = [&map_cache]( point p ) {
674 return map_cache.transparency_cache[p.x][p.y] <= LIGHT_TRANSPARENCY_SOLID &&
675 get_player_character().pos().xy() != p;
676 };
677
678 const bool p_opaque = is_opaque( p.xy() );
679 float apparent_light;
680
681 if( p_opaque && vis > 0 ) {
682 // This is the complicated case. We want to check which quadrants the
683 // player can see the tile from, and only count light values from those
684 // quadrants.
685 struct offset_and_quadrants {
686 point offset;
687 std::array<quadrant, 2> quadrants;
688 };
689 static constexpr std::array<offset_and_quadrants, 8> adjacent_offsets = {{
698 }
699 };
700
701 four_quadrants seen_from( 0 );
702 for( const offset_and_quadrants &oq : adjacent_offsets ) {
703 const point neighbour = p.xy() + oq.offset;
704
705 if( !lightmap_boundaries.contains( neighbour ) ) {
706 continue;
707 }
708 if( is_opaque( neighbour ) ) {
709 continue;
710 }
711 if( map_cache.seen_cache[neighbour.x][neighbour.y] == 0 &&
712 map_cache.camera_cache[neighbour.x][neighbour.y] == 0 ) {
713 continue;
714 }
715 // This is a non-opaque visible neighbour, so count visibility from the relevant
716 // quadrants
717 seen_from[oq.quadrants[0]] = vis;
718 seen_from[oq.quadrants[1]] = vis;
719 }
720 apparent_light = ( seen_from * map_cache.lm[p.x][p.y] ).max();
721 } else {
722 // This is the simple case, for a non-opaque tile light from all
723 // directions is equivalent
724 apparent_light = vis * map_cache.lm[p.x][p.y].max();
725 }
726 return { obstructed, apparent_light };
727}
const half_open_rectangle< point > lightmap_boundaries(lightmap_boundary_min, lightmap_boundary_max)
static constexpr float LIGHT_TRANSPARENCY_SOLID
Transparency 101: Transparency usually ranges between 0.038 (open air) and 0.38 (regular smoke).
Definition: lightmap.h:32
static constexpr point point_south_west
Definition: point.h:267
static constexpr point point_west
Definition: point.h:268
static constexpr point point_north_east
Definition: point.h:263
static constexpr point point_north_west
Definition: point.h:269
static constexpr point point_south_east
Definition: point.h:265
static constexpr point point_south
Definition: point.h:266
static constexpr point point_north
Definition: point.h:262
static constexpr point point_east
Definition: point.h:264
float seen_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:343
float transparency_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:332
float camera_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:347
int y
Definition: point.h:39
int x
Definition: point.h:38

References level_cache::camera_cache, get_player_character(), LIGHT_TRANSPARENCY_SOLID, lightmap_boundaries, level_cache::lm, four_quadrants::max(), NE, NW, point_east, point_north, point_north_east, point_north_west, point_south, point_south_east, point_south_west, point_west, Character::pos(), SE, level_cache::seen_cache, SW, level_cache::transparency_cache, point::x, tripoint::x, tripoint::xy(), point::y, and tripoint::y.

Referenced by apparent_light_at(), pl_sees(), and editmap::update_view_with_help().

◆ apply_character_light()

void map::apply_character_light ( Character p)
protected

Definition at line 227 of file lightmap.cpp.

228{
229 if( p.has_effect( effect_onfire ) ) {
230 apply_light_source( p.pos(), 8 );
231 } else if( p.has_effect( effect_haslight ) ) {
232 apply_light_source( p.pos(), 4 );
233 }
234
235 const float held_luminance = p.active_light();
236 if( held_luminance > LIGHT_AMBIENT_LOW ) {
237 apply_light_source( p.pos(), held_luminance );
238 }
239
240 if( held_luminance >= 4 && held_luminance > ambient_light_at( p.pos() ) - 0.5f ) {
241 p.add_effect( effect_haslight, 1_turns );
242 }
243}
float active_light() const
Returns character luminosity based on the brightest active item they are carrying.
Definition: character.cpp:6272
void add_effect(const effect &eff, bool force=false, bool deferred=false)
Definition: creature.cpp:986
bool has_effect(const efftype_id &eff_id, body_part bp=num_bp) const
Check if creature has the matching effect.
Definition: creature.cpp:1185
void apply_light_source(const tripoint &p, float luminance)
Definition: lightmap.cpp:1543
float ambient_light_at(const tripoint &p) const
Definition: lightmap.cpp:646
static const efftype_id effect_haslight("haslight")
static const efftype_id effect_onfire("onfire")
static constexpr float LIGHT_AMBIENT_LOW
Definition: lightmap.h:14

References Character::active_light(), Creature::add_effect(), ambient_light_at(), apply_light_source(), effect_haslight, effect_onfire, Creature::has_effect(), LIGHT_AMBIENT_LOW, and Character::pos().

Referenced by generate_lightmap().

◆ apply_directional_light()

void map::apply_directional_light ( const tripoint p,
int  direction,
float  luminance 
)
private

Definition at line 1624 of file lightmap.cpp.

1625{
1626 const point p2( p.xy() );
1627
1628 auto &cache = get_cache( p.z );
1629 four_quadrants( &lm )[MAPSIZE_X][MAPSIZE_Y] = cache.lm;
1630 float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = cache.transparency_cache;
1631 diagonal_blocks( &blocked_cache )[MAPSIZE_X][MAPSIZE_Y] = cache.vehicle_obscured_cache;
1632
1633 if( direction == 90 ) {
1634 castLight < 1, 0, 0, -1, float, four_quadrants, light_calc, light_check,
1636 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1637 castLight < -1, 0, 0, -1, float, four_quadrants, light_calc, light_check,
1639 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1640 } else if( direction == 0 ) {
1641 castLight < 0, -1, 1, 0, float, four_quadrants, light_calc, light_check,
1643 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1644 castLight < 0, -1, -1, 0, float, four_quadrants, light_calc, light_check,
1646 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1647 } else if( direction == 270 ) {
1648 castLight<1, 0, 0, 1, float, four_quadrants, light_calc, light_check,
1650 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1651 castLight < -1, 0, 0, 1, float, four_quadrants, light_calc, light_check,
1653 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1654 } else if( direction == 180 ) {
1655 castLight<0, 1, 1, 0, float, four_quadrants, light_calc, light_check,
1657 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1658 castLight < 0, 1, -1, 0, float, four_quadrants, light_calc, light_check,
1660 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1661 }
1662}
static constexpr int MAPSIZE_Y
static constexpr int MAPSIZE_X
static bool light_check(const float &transparency, const float &intensity)
Definition: lightmap.cpp:1538
void castLight(Out(&output_cache)[MAPSIZE_X][MAPSIZE_Y], const T(&input_array)[MAPSIZE_X][MAPSIZE_Y], const diagonal_blocks(&blocked_array)[MAPSIZE_X][MAPSIZE_Y], point offset, int offsetDistance, T numerator=VISIBILITY_FULL, int row=1, float start=1.0f, float end=0.0f, T cumulative_transparency=LIGHT_TRANSPARENCY_OPEN_AIR)
Definition: lightmap.cpp:1155
static float light_calc(const float &numerator, const float &transparency, const int &distance)
Definition: lightmap.cpp:1531
direction
Definition: line.h:39
void update_light_quadrants(four_quadrants &update, const float &new_value, quadrant q)
Definition: shadowcasting.h:97
float accumulate_transparency(const float &cumulative_transparency, const float &current_transparency, const int &distance)

References accumulate_transparency(), castLight(), get_cache(), light_calc(), light_check(), MAPSIZE_X, MAPSIZE_Y, update_light_quadrants(), tripoint::xy(), and tripoint::z.

Referenced by generate_lightmap().

◆ apply_faction_ownership()

void map::apply_faction_ownership ( point  p1,
point  p2,
const faction_id id 
)

Definition at line 5531 of file mapgen.cpp.

5532{
5533 for( const tripoint &p : points_in_rectangle( tripoint( p1, abs_sub.z ), tripoint( p2,
5534 abs_sub.z ) ) ) {
5535 auto items = i_at( p.xy() );
5536 for( item &elem : items ) {
5537 elem.set_owner( id );
5538 }
5539 vehicle *source_veh = veh_pointer_or_null( veh_at( p ) );
5540 if( source_veh ) {
5541 if( !source_veh->has_owner() ) {
5542 source_veh->set_owner( id );
5543 }
5544 }
5545 }
5546}
tripoint_range< tripoint > points_in_rectangle(const tripoint &from, const tripoint &to) const
Definition: map.cpp:8669
bool has_owner() const
Definition: vehicle.h:845
void set_owner(const faction_id &new_owner)
Definition: vehicle.h:832

References abs_sub, vehicle::has_owner(), i_at(), points_in_rectangle(), vehicle::set_owner(), veh_at(), veh_pointer_or_null(), and tripoint::z.

Referenced by jmapgen_faction::apply().

◆ apply_light_arc()

void map::apply_light_arc ( const tripoint p,
units::angle  angle,
float  luminance,
units::angle  wideangle = 30_degrees 
)
private

Definition at line 1664 of file lightmap.cpp.

1666{
1667 if( luminance <= LIGHT_SOURCE_LOCAL ) {
1668 return;
1669 }
1670
1671 bool lit[LIGHTMAP_CACHE_X][LIGHTMAP_CACHE_Y] {};
1672
1674
1675 // Normalize (should work with negative values too)
1676 const units::angle wangle = wideangle / 2.0;
1677
1678 units::angle nangle = fmod( angle, 360_degrees );
1679
1680 tripoint end;
1681 int range = LIGHT_RANGE( luminance );
1682 calc_ray_end( nangle, range, p, end );
1683 apply_light_ray( lit, p, end, luminance );
1684
1685 tripoint test;
1686 calc_ray_end( wangle + nangle, range, p, test );
1687
1688 const float wdist = hypot( end.x - test.x, end.y - test.y );
1689 if( wdist <= 0.5 ) {
1690 return;
1691 }
1692
1693 // attempt to determine beam intensity required to cover all squares
1694 const units::angle wstep = ( wangle / ( wdist * M_SQRT2 ) );
1695
1696 // NOLINTNEXTLINE(clang-analyzer-security.FloatLoopCounter)
1697 for( units::angle ao = wstep; ao <= wangle; ao += wstep ) {
1698 if( trigdist ) {
1699 double fdist = ( ao * M_PI_2 ) / wangle;
1700 end.x = static_cast<int>(
1701 p.x + ( static_cast<double>( range ) - fdist * 2.0 ) * cos( nangle + ao ) );
1702 end.y = static_cast<int>(
1703 p.y + ( static_cast<double>( range ) - fdist * 2.0 ) * sin( nangle + ao ) );
1704 apply_light_ray( lit, p, end, luminance );
1705
1706 end.x = static_cast<int>(
1707 p.x + ( static_cast<double>( range ) - fdist * 2.0 ) * cos( nangle - ao ) );
1708 end.y = static_cast<int>(
1709 p.y + ( static_cast<double>( range ) - fdist * 2.0 ) * sin( nangle - ao ) );
1710 apply_light_ray( lit, p, end, luminance );
1711 } else {
1712 calc_ray_end( nangle + ao, range, p, end );
1713 apply_light_ray( lit, p, end, luminance );
1714 calc_ray_end( nangle - ao, range, p, end );
1715 apply_light_ray( lit, p, end, luminance );
1716 }
1717 }
1718}
bool trigdist
Circular distances.
void apply_light_ray(bool lit[MAPSIZE_X][MAPSIZE_Y], const tripoint &s, const tripoint &e, float luminance)
Definition: lightmap.cpp:1720
static constexpr int LIGHTMAP_CACHE_Y
Definition: lightmap.cpp:49
static constexpr int LIGHTMAP_CACHE_X
Definition: lightmap.cpp:48
static constexpr float LIGHT_SOURCE_LOCAL
Definition: lightmap.h:8
#define LIGHT_RANGE(b)
Definition: lightmap.h:41
void calc_ray_end(units::angle angle, const int range, const tripoint &p, tripoint &out)
Definition: line.cpp:751
#define M_SQRT2
Definition: math_defines.h:29
#define M_PI_2
Definition: math_defines.h:25
quantity< double, angle_in_radians_tag > angle
Definition: units_angle.h:17
double sin(angle a)
Definition: units_angle.h:52
double cos(angle a)
Definition: units_angle.h:57
quantity< V, U > fmod(quantity< V, U > num, quantity< V, U > den)
Definition: units_def.h:142

References apply_light_ray(), apply_light_source(), calc_ray_end(), units::cos(), units::fmod(), LIGHT_RANGE, LIGHT_SOURCE_LOCAL, LIGHTMAP_CACHE_X, LIGHTMAP_CACHE_Y, M_PI_2, M_SQRT2, units::sin(), trigdist, tripoint::x, and tripoint::y.

Referenced by add_light_from_items(), and generate_lightmap().

◆ apply_light_ray()

void map::apply_light_ray ( bool  lit[MAPSIZE_X][MAPSIZE_Y],
const tripoint s,
const tripoint e,
float  luminance 
)
private

Definition at line 1720 of file lightmap.cpp.

1722{
1723 point a( std::abs( e.x - s.x ) * 2, std::abs( e.y - s.y ) * 2 );
1724 point d( ( s.x < e.x ) ? 1 : -1, ( s.y < e.y ) ? 1 : -1 );
1725 point p( s.xy() );
1726
1727 quadrant quad = quadrant_from_x_y( d.x, d.y );
1728
1729 // TODO: Invert that z comparison when it's sane
1730 if( s.z != e.z || ( s.x == e.x && s.y == e.y ) ) {
1731 return;
1732 }
1733
1734 auto &lm = get_cache( s.z ).lm;
1735 auto &transparency_cache = get_cache( s.z ).transparency_cache;
1736
1737 float distance = 1.0;
1738 float transparency = LIGHT_TRANSPARENCY_OPEN_AIR;
1739 const float scaling_factor = static_cast<float>( rl_dist( s, e ) ) /
1740 static_cast<float>( square_dist( s, e ) );
1741 // TODO: [lightmap] Pull out the common code here rather than duplication
1742 if( a.x > a.y ) {
1743 int t = a.y - ( a.x / 2 );
1744 do {
1745 if( t >= 0 ) {
1746 p.y += d.y;
1747 t -= a.x;
1748 }
1749
1750 p.x += d.x;
1751 t += a.y;
1752
1753 // TODO: clamp coordinates to map bounds before this method is called.
1754 if( lightmap_boundaries.contains( p ) ) {
1755 float current_transparency = transparency_cache[p.x][p.y];
1756 bool is_opaque = ( current_transparency == LIGHT_TRANSPARENCY_SOLID );
1757 if( !lit[p.x][p.y] ) {
1758 // Multiple rays will pass through the same squares so we need to record that
1759 lit[p.x][p.y] = true;
1760 float lm_val = luminance / ( fastexp( transparency * distance ) * distance );
1761 quadrant q = is_opaque ? quad : quadrant::default_;
1762 lm[p.x][p.y][q] = std::max( lm[p.x][p.y][q], lm_val );
1763 }
1764 if( is_opaque ) {
1765 break;
1766 }
1767 // Cumulative average of the transparency values encountered.
1768 transparency = ( ( distance - 1.0 ) * transparency + current_transparency ) / distance;
1769 } else {
1770 break;
1771 }
1772
1773 distance += scaling_factor;
1774 } while( !( p.x == e.x && p.y == e.y ) );
1775 } else {
1776 int t = a.x - ( a.y / 2 );
1777 do {
1778 if( t >= 0 ) {
1779 p.x += d.x;
1780 t -= a.y;
1781 }
1782
1783 p.y += d.y;
1784 t += a.x;
1785
1786 if( lightmap_boundaries.contains( p ) ) {
1787 float current_transparency = transparency_cache[p.x][p.y];
1788 bool is_opaque = ( current_transparency == LIGHT_TRANSPARENCY_SOLID );
1789 if( !lit[p.x][p.y] ) {
1790 // Multiple rays will pass through the same squares so we need to record that
1791 lit[p.x][p.y] = true;
1792 float lm_val = luminance / ( fastexp( transparency * distance ) * distance );
1793 quadrant q = is_opaque ? quad : quadrant::default_;
1794 lm[p.x][p.y][q] = std::max( lm[p.x][p.y][q], lm_val );
1795 }
1796 if( is_opaque ) {
1797 break;
1798 }
1799 // Cumulative average of the transparency values encountered.
1800 transparency = ( ( distance - 1.0 ) * transparency + current_transparency ) / distance;
1801 } else {
1802 break;
1803 }
1804
1805 distance += scaling_factor;
1806 } while( !( p.x == e.x && p.y == e.y ) );
1807 }
1808}
int square_dist(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:505
static constexpr quadrant quadrant_from_x_y(int x, int y)
Definition: lightmap.cpp:815
static float fastexp(float x)
Definition: lightmap.cpp:1515
static constexpr float LIGHT_TRANSPARENCY_OPEN_AIR
Definition: lightmap.h:36
quadrant
Definition: shadowcasting.h:22

References a, default_, fastexp(), get_cache(), LIGHT_TRANSPARENCY_OPEN_AIR, LIGHT_TRANSPARENCY_SOLID, lightmap_boundaries, level_cache::lm, quadrant_from_x_y(), rl_dist(), square_dist(), level_cache::transparency_cache, point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, and tripoint::z.

Referenced by apply_light_arc().

◆ apply_light_source()

void map::apply_light_source ( const tripoint p,
float  luminance 
)
private

Definition at line 1543 of file lightmap.cpp.

1544{
1545 auto &cache = get_cache( p.z );
1546 four_quadrants( &lm )[MAPSIZE_X][MAPSIZE_Y] = cache.lm;
1547 float ( &sm )[MAPSIZE_X][MAPSIZE_Y] = cache.sm;
1548 float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = cache.transparency_cache;
1549 float ( &light_source_buffer )[MAPSIZE_X][MAPSIZE_Y] = cache.light_source_buffer;
1550 diagonal_blocks( &blocked_cache )[MAPSIZE_X][MAPSIZE_Y] = cache.vehicle_obscured_cache;
1551
1552 const point p2( p.xy() );
1553
1554 if( inbounds( p ) ) {
1555 const float min_light = std::max( static_cast<float>( lit_level::LOW ), luminance );
1556 lm[p2.x][p2.y] = elementwise_max( lm[p2.x][p2.y], min_light );
1557 sm[p2.x][p2.y] = std::max( sm[p2.x][p2.y], luminance );
1558 }
1559 if( luminance <= lit_level::LOW ) {
1560 return;
1561 } else if( luminance <= lit_level::BRIGHT_ONLY ) {
1562 luminance = 1.49f;
1563 }
1564
1565 /* If we're a 5 luminance fire , we skip casting rays into ey && sx if we have
1566 neighboring fires to the north and west that were applied via light_source_buffer
1567 If there's a 1 luminance candle east in buffer, we still cast rays into ex since it's smaller
1568 If there's a 100 luminance magnesium flare south added via apply_light_source instead od
1569 add_light_source, it's unbuffered so we'll still cast rays into sy.
1570
1571 ey
1572 nnnNnnn
1573 w e
1574 w 5 +e
1575 sx W 5*1+E ex
1576 w ++++e
1577 w+++++e
1578 sssSsss
1579 sy
1580 */
1581 const int peer_inbounds = LIGHTMAP_CACHE_X - 1;
1582 bool north = ( p2.y != 0 && light_source_buffer[p2.x][p2.y - 1] < luminance );
1583 bool south = ( p2.y != peer_inbounds && light_source_buffer[p2.x][p2.y + 1] < luminance );
1584 bool east = ( p2.x != peer_inbounds && light_source_buffer[p2.x + 1][p2.y] < luminance );
1585 bool west = ( p2.x != 0 && light_source_buffer[p2.x - 1][p2.y] < luminance );
1586
1587 if( north ) {
1588 castLight < 1, 0, 0, -1, float, four_quadrants, light_calc, light_check,
1590 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1591 castLight < -1, 0, 0, -1, float, four_quadrants, light_calc, light_check,
1593 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1594 }
1595
1596 if( east ) {
1597 castLight < 0, -1, 1, 0, float, four_quadrants, light_calc, light_check,
1599 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1600 castLight < 0, -1, -1, 0, float, four_quadrants, light_calc, light_check,
1602 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1603 }
1604
1605 if( south ) {
1606 castLight<1, 0, 0, 1, float, four_quadrants, light_calc, light_check,
1608 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1609 castLight < -1, 0, 0, 1, float, four_quadrants, light_calc, light_check,
1611 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1612 }
1613
1614 if( west ) {
1615 castLight<0, 1, 1, 0, float, four_quadrants, light_calc, light_check,
1617 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1618 castLight < 0, 1, -1, 0, float, four_quadrants, light_calc, light_check,
1620 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1621 }
1622}
constexpr scale sm
Definition: coordinates.h:31

References accumulate_transparency(), BRIGHT_ONLY, castLight(), get_cache(), inbounds(), light_calc(), light_check(), LIGHTMAP_CACHE_X, LOW, MAPSIZE_X, MAPSIZE_Y, coords::sm, update_light_quadrants(), point::x, tripoint::xy(), point::y, and tripoint::z.

Referenced by apply_character_light(), apply_light_arc(), and generate_lightmap().

◆ apply_vision_transparency_cache()

void map::apply_vision_transparency_cache ( const tripoint center,
int  target_z,
float(&)  vision_restore_cache[9],
bool(&)  blocked_restore_cache[8] 
)
protected

Definition at line 1313 of file lightmap.cpp.

1315{
1316 level_cache &map_cache = get_cache( target_z );
1317 float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.transparency_cache;
1318 diagonal_blocks( &blocked_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.vehicle_obscured_cache;
1319
1320 int i = 0;
1321 for( point adjacent : eight_adjacent_offsets ) {
1322 const tripoint p = center + adjacent;
1323 if( !inbounds( p ) ) {
1324 continue;
1325 }
1326 vision_restore_cache[i] = transparency_cache[p.x][p.y];
1328 transparency_cache[p.x][p.y] = LIGHT_TRANSPARENCY_SOLID;
1330
1332 adjacent ) == four_diagonal_offsets.end() ) {
1333 debugmsg( "Hidden tile not on a diagonal" );
1334 continue;
1335 }
1336
1337 bool &relevant_blocked = adjacent == point_north_east ? blocked_cache[center.x][center.y].ne :
1338 adjacent == point_south_east ? blocked_cache[p.x][p.y].nw :
1339 adjacent == point_south_west ? blocked_cache[p.x][p.y].ne :
1340 /* point_north_west */ blocked_cache[center.x][center.y].nw;
1341
1342 //We only set the restore cache if we actually flip the bit
1343 blocked_restore_cache[i] = !relevant_blocked;
1344
1345 relevant_blocked = true;
1346 }
1347 i++;
1348 }
1349 vision_restore_cache[8] = transparency_cache[center.x][center.y];
1350}
vision_adjustment vision_transparency_cache[8]
Definition: map.h:1774
@ VISION_ADJUST_HIDDEN
Definition: lightmap.h:79
@ VISION_ADJUST_SOLID
Definition: lightmap.h:78
FMT_CONSTEXPR bool find(Ptr first, Ptr last, T value, Ptr &out)
static constexpr std::array< point, 8 > eight_adjacent_offsets
Definition: point.h:352
static constexpr std::array< point, 4 > four_diagonal_offsets
Definition: point.h:348
diagonal_blocks vehicle_obscured_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:336

References center, debugmsg, eight_adjacent_offsets, detail::find(), four_diagonal_offsets, get_cache(), inbounds(), LIGHT_TRANSPARENCY_SOLID, MAPSIZE_X, MAPSIZE_Y, point_north_east, point_south_east, point_south_west, level_cache::transparency_cache, level_cache::vehicle_obscured_cache, VISION_ADJUST_HIDDEN, VISION_ADJUST_SOLID, vision_transparency_cache, tripoint::x, and tripoint::y.

Referenced by build_seen_cache().

◆ bash()

bash_results map::bash ( const tripoint p,
int  str,
bool  silent = false,
bool  destroy = false,
bool  bash_floor = false,
const vehicle bashing_vehicle = nullptr 
)

Returns a pair where first is whether anything was smashed and second is if it was destroyed.

Parameters
pWhere to bash
strHow hard to bash
silentDon't produce any sound
destroyDestroys some otherwise unbashable tiles
bash_floorAllow bashing the floor and the tile that supports it
bashing_vehicleVehicle that should NOT be bashed (because it is doing the bashing)

Definition at line 3585 of file map.cpp.

3588{
3589 bash_params bsh{
3590 str, silent, destroy, bash_floor, static_cast<float>( rng_float( 0, 1.0f ) ), false, true
3591 };
3593 if( !inbounds( p ) ) {
3594 return result;
3595 }
3596
3597 bool bashed_sealed = false;
3598 if( has_flag( "SEALED", p ) ) {
3599 result |= bash_ter_furn( p, bsh );
3600 bashed_sealed = true;
3601 }
3602
3603 result |= bash_field( p, bsh );
3604
3605 // Don't bash items inside terrain/furniture with SEALED flag
3606 if( !bashed_sealed ) {
3607 result |= bash_items( p, bsh );
3608 }
3609 // Don't bash the vehicle doing the bashing
3610 const vehicle *veh = veh_pointer_or_null( veh_at( p ) );
3611 if( veh != nullptr && veh != bashing_vehicle ) {
3612 result |= bash_vehicle( p, bsh );
3613 }
3614
3615 // If we still didn't bash anything solid (a vehicle) or a tile with SEALED flag, bash ter/furn
3616 if( !result.bashed_solid && !bashed_sealed ) {
3617 result |= bash_ter_furn( p, bsh );
3618 }
3619
3620 return result;
3621}
bash_results bash_field(const tripoint &p, const bash_params &params)
Definition: map.cpp:3675
bash_results bash_items(const tripoint &p, const bash_params &params)
Definition: map.cpp:3623
bash_results bash_vehicle(const tripoint &p, const bash_params &params)
Definition: map.cpp:3657
bash_results bash_ter_furn(const tripoint &p, const bash_params &params)
Definition: map.cpp:3461
double rng_float(double lo, double hi)
Definition: rng.cpp:28
@ silent
Definition: weather_type.h:56

References bash_field(), bash_items(), bash_ter_furn(), bash_vehicle(), destroy(), has_flag(), inbounds(), rng_float(), silent, veh_at(), and veh_pointer_or_null().

Referenced by Character::activate_bionic(), jmapgen_setmap::apply(), spell_effect::bash(), bash_furn_success(), bash_resistance(), bash_strength(), bash_ter_furn(), bash_ter_success(), batter(), destroy(), destroy_furn(), explosion_handler::do_blast(), drop_furniture(), drop_items(), game::fling_creature(), is_bashable(), game::knockback(), npc::move_to(), vehicle::part_collision(), Character::reach_attack(), route(), scatter_chunks(), shoot(), explosion_handler::shrapnel(), mattack::shriek_stun(), smash(), and valid_move().

◆ bash_field()

bash_results map::bash_field ( const tripoint p,
const bash_params params 
)

Definition at line 3675 of file map.cpp.

3676{
3678 if( get_field( p, fd_web ) != nullptr ) {
3679 result.did_bash = true;
3680 result.bashed_solid = true; // To prevent bashing furniture/vehicles
3681 remove_field( p, fd_web );
3682 }
3683
3684 return result;
3685}
void remove_field(const tripoint &p, const field_type_id &field_to_remove)
Remove field entry at xy, ignored if the field entry is not present.
Definition: map.cpp:5526
field_type_id fd_web
Definition: field_type.cpp:340

References fd_web, get_field(), and remove_field().

Referenced by bash().

◆ bash_furn_success()

bash_results map::bash_furn_success ( const tripoint p,
const bash_params params 
)

Definition at line 3361 of file map.cpp.

3362{
3364 const auto &furnid = furn( p ).obj();
3365 const map_bash_info &bash = furnid.bash;
3366
3367
3368 if( has_flag_furn( "FUNGUS", p ) ) {
3369 fungal_effects( *g, *this ).create_spores( p );
3370 }
3371 if( has_flag_furn( "MIGO_NERVE", p ) ) {
3372 map_funcs::migo_nerve_cage_removal( *this, p, true );
3373 }
3374 std::string soundfxvariant = furnid.id.str();
3375 const bool tent = !bash.tent_centers.empty();
3376
3377 // Special code to collapse the tent if destroyed
3378 if( tent ) {
3379 // Get ids of possible centers
3380 std::set<furn_id> centers;
3381 for( const auto &cur_id : bash.tent_centers ) {
3382 if( cur_id.is_valid() ) {
3383 centers.insert( cur_id );
3384 }
3385 }
3386
3388
3389 // Find the center of the tent
3390 // First check if we're not currently bashing the center
3391 if( centers.count( furn( p ) ) > 0 ) {
3392 tentp.emplace( p, furn( p ) );
3393 } else {
3394 for( const tripoint &pt : points_in_radius( p, bash.collapse_radius ) ) {
3395 const furn_id &f_at = furn( pt );
3396 // Check if we found the center of the current tent
3397 if( centers.count( f_at ) > 0 ) {
3398 tentp.emplace( pt, f_at );
3399 break;
3400 }
3401 }
3402 }
3403 // Didn't find any tent center, wreck the current tile
3404 if( !tentp ) {
3406 furn_set( p, bash.furn_set );
3407 } else {
3408 // Take the tent down
3409 const int rad = tentp->second.obj().bash.collapse_radius;
3410 for( const tripoint &pt : points_in_radius( tentp->first, rad ) ) {
3411 const furn_id frn = furn( pt );
3412 if( frn == f_null ) {
3413 continue;
3414 }
3415
3416 const map_bash_info &recur_bash = frn.obj().bash;
3417 // Check if we share a center type and thus a "tent type"
3418 for( const auto &cur_id : recur_bash.tent_centers ) {
3419 if( centers.count( cur_id.id() ) > 0 ) {
3420 // Found same center, wreck current tile
3422 furn_set( pt, recur_bash.furn_set );
3423 break;
3424 }
3425 }
3426 }
3427 }
3428 soundfxvariant = "smash_cloth";
3429 } else {
3430 furn_set( p, bash.furn_set );
3431 for( item &it : i_at( p ) ) {
3432 it.on_drop( p, *this );
3433 }
3434 // HACK: Hack alert.
3435 // Signs have cosmetics associated with them on the submap since
3436 // furniture can't store dynamic data to disk. To prevent writing
3437 // mysteriously appearing for a sign later built here, remove the
3438 // writing from the submap.
3439 delete_signage( p );
3440 }
3441
3442 if( !tent ) {
3444 }
3445
3446 if( !bash.sound.empty() && !params.silent ) {
3447 static const std::string soundfxid = "smash_success";
3448 int sound_volume = get_sound_volume( bash );
3449 sounds::sound( p, sound_volume, sounds::sound_t::combat, bash.sound, false,
3450 soundfxid, soundfxvariant );
3451 }
3452
3453 if( bash.explosive > 0 ) {
3454 // TODO implement if the player triggered the explosive furniture
3455 explosion_handler::explosion( p, nullptr, bash.explosive, 0.8, false );
3456 }
3457
3458 return result;
3459}
T & emplace(Args &&... args)
Definition: optional.h:146
void create_spores(const tripoint &p, Creature *origin=nullptr)
Makes spores at p.
bool has_flag_furn(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2375
bash_results bash(const tripoint &p, int str, bool silent=false, bool destroy=false, bool bash_floor=false, const vehicle *bashing_vehicle=nullptr)
Returns a pair where first is whether anything was smashed and second is if it was destroyed.
Definition: map.cpp:3585
std::vector< item * > spawn_items(const tripoint &p, const std::vector< item > &new_items)
Definition: map.cpp:4222
void furn_set(const tripoint &p, const furn_id &new_furniture, cata::poly_serialized< active_tile_data > new_active=nullptr)
Sets the furniture at given position.
Definition: map.cpp:1418
void delete_signage(const tripoint &p) const
Definition: map.cpp:4081
static int get_sound_volume(const map_bash_info &bash)
Definition: map.cpp:3223
furn_id f_null
Definition: mapdata.cpp:1097
void explosion(const tripoint &p, Creature *source, float power, float factor, bool fire, int legacy_casing_mass, float)
Legacy explosion function.
Definition: explosion.cpp:785
ItemList items_from(const item_group_id &group_id, const time_point &birthday)
Create items from the given group.
Definition: item_group.cpp:574
void migo_nerve_cage_removal(map &m, const tripoint &p, bool spawn_damaged)
void sound(const tripoint &p, int vol, sound_t category, const std::string &description, bool ambient=false, const std::string &id="", const std::string &variant="default")
Sound at (p) of intensity (vol)
Definition: sounds.cpp:177
@ rad
Must be irradiated/in irradiated tile.
bool silent
Definition: map.h:136
std::vector< furn_str_id > tent_centers
Definition: mapdata.h:100
item_group_id drop_group
Definition: mapdata.h:86
furn_str_id furn_set
Definition: mapdata.h:98
map_bash_info bash
Definition: mapdata.h:346

References bash(), map_data_common_t::bash, sounds::combat, fungal_effects::create_spores(), delete_signage(), map_bash_info::drop_group, cata::optional< T >::emplace(), explosion_handler::explosion(), f_null, furn(), furn_set(), map_bash_info::furn_set, g, get_sound_volume(), has_flag_furn(), i_at(), item_group::items_from(), map_funcs::migo_nerve_cage_removal(), int_id< T >::obj(), points_in_radius(), rad, bash_params::silent, sounds::sound(), spawn_items(), map_bash_info::tent_centers, and calendar::turn.

Referenced by bash_ter_furn().

◆ bash_items()

bash_results map::bash_items ( const tripoint p,
const bash_params params 
)

Definition at line 3623 of file map.cpp.

3624{
3626 if( !has_items( p ) ) {
3627 return result;
3628 }
3629
3630 std::vector<item> smashed_contents;
3631 auto bashed_items = i_at( p );
3632 bool smashed_glass = false;
3633 for( auto bashed_item = bashed_items.begin(); bashed_item != bashed_items.end(); ) {
3634 // the check for active suppresses Molotovs smashing themselves with their own explosion
3635 if( bashed_item->made_of( material_id( "glass" ) ) && !bashed_item->active && one_in( 2 ) ) {
3636 result.did_bash = true;
3637 smashed_glass = true;
3638 for( const item *bashed_content : bashed_item->contents.all_items_top() ) {
3639 smashed_contents.push_back( item( *bashed_content ) );
3640 }
3641 bashed_item = bashed_items.erase( bashed_item );
3642 } else {
3643 ++bashed_item;
3644 }
3645 }
3646 // Now plunk in the contents of the smashed items.
3647 spawn_items( p, smashed_contents );
3648
3649 // Add a glass sound even when something else also breaks
3650 if( smashed_glass && !params.silent ) {
3651 sounds::sound( p, 12, sounds::sound_t::combat, _( "glass shattering" ), false,
3652 "smash_success", "smash_glass_contents" );
3653 }
3654 return result;
3655}
std::list< item * > all_items_top()
returns a list of pointers to all top-level items
item_contents contents
Definition: item.h:2158
bool has_items(const tripoint &p) const
Checks for existence of items.
Definition: map.cpp:4830

References _, item_contents::all_items_top(), sounds::combat, item::contents, has_items(), i_at(), one_in(), bash_params::silent, sounds::sound(), and spawn_items().

Referenced by bash().

◆ bash_rating() [1/2]

int map::bash_rating ( const int  str,
point  p 
) const
inline

Definition at line 991 of file map.h.

991 {
992 return bash_rating( str, tripoint( p, abs_sub.z ) );
993 }
int bash_rating(int str, const tripoint &p, bool allow_floor=false) const
Returns a success rating from -1 to 10 for a given tile based on a set strength, used for AI movement...
Definition: map.cpp:2546

References abs_sub, bash_rating(), and tripoint::z.

◆ bash_rating() [2/2]

int map::bash_rating ( int  str,
const tripoint p,
bool  allow_floor = false 
) const

Returns a success rating from -1 to 10 for a given tile based on a set strength, used for AI movement planning Values roughly correspond to 10% increment chances of success on a given bash, rounded down.

-1 means the square is not bashable

Definition at line 2546 of file map.cpp.

2547{
2548 if( !inbounds( p ) ) {
2549 dbg( DL::Warn ) << "Looking for out-of-bounds is_bashable at " << p;
2550 return -1;
2551 }
2552
2553 if( str <= 0 ) {
2554 return -1;
2555 }
2556
2557 const furn_t &furniture = furn( p ).obj();
2558 const ter_t &terrain = ter( p ).obj();
2559 const optional_vpart_position vp = veh_at( p );
2560 vehicle *const veh = vp ? &vp->vehicle() : nullptr;
2561 const int part = vp ? vp->part_index() : -1;
2562 return bash_rating_internal( str, furniture, terrain, allow_floor, veh, part );
2563}
int bash_rating_internal(int str, const furn_t &furniture, const ter_t &terrain, bool allow_floor, const vehicle *veh, int part) const
Definition: map.cpp:2438

References bash_rating_internal(), dbg, furn(), furniture, inbounds(), int_id< T >::obj(), ter(), terrain, veh_at(), and Warn.

Referenced by bash_rating(), npc::can_move_to(), monster::move(), and npc::move_to().

◆ bash_rating_internal()

int map::bash_rating_internal ( int  str,
const furn_t furniture,
const ter_t terrain,
bool  allow_floor,
const vehicle veh,
int  part 
) const
private
Strength determines what furniture can be smashed Strength determines what terrain can be smashed Strength increases smashing damage

Definition at line 2438 of file map.cpp.

2441{
2442 bool furn_smash = false;
2443 bool ter_smash = false;
2444 ///\EFFECT_STR determines what furniture can be smashed
2445 if( furniture.id && furniture.bash.str_max != -1 ) {
2446 furn_smash = true;
2447 ///\EFFECT_STR determines what terrain can be smashed
2448 } else if( terrain.bash.str_max != -1 && ( !terrain.bash.bash_below || allow_floor ) ) {
2449 ter_smash = true;
2450 }
2451
2452 if( veh != nullptr && vpart_position( const_cast<vehicle &>( *veh ), part ).obstacle_at_part() ) {
2453 // Monsters only care about rating > 0, NPCs should want to path around cars instead
2454 return 2; // Should probably be a function of part hp (+armor on tile)
2455 }
2456
2457 int bash_min = 0;
2458 int bash_max = 0;
2459 if( furn_smash ) {
2460 bash_min = furniture.bash.str_min;
2461 bash_max = furniture.bash.str_max;
2462 } else if( ter_smash ) {
2463 bash_min = terrain.bash.str_min;
2464 bash_max = terrain.bash.str_max;
2465 } else {
2466 return -1;
2467 }
2468
2469 ///\EFFECT_STR increases smashing damage
2470 if( str < bash_min ) {
2471 return 0;
2472 } else if( str >= bash_max ) {
2473 return 10;
2474 }
2475
2476 int ret = ( 10 * ( str - bash_min ) ) / ( bash_max - bash_min );
2477 // Round up to 1, so that desperate NPCs can try to bash down walls
2478 return std::max( ret, 1 );
2479}
Reference to a position (a point) of the vehicle.

References furniture, cata::hash64_detail::ret, and terrain.

Referenced by bash_rating(), and route().

◆ bash_resistance() [1/2]

int map::bash_resistance ( const tripoint p,
bool  allow_floor = false 
) const

Returns min_str of the furniture or terrain at p.

Definition at line 2532 of file map.cpp.

2533{
2534 if( has_furn( p ) && furn( p ).obj().bash.str_min != -1 ) {
2535 return furn( p ).obj().bash.str_min;
2536 }
2537
2538 const auto &ter_bash = ter( p ).obj().bash;
2539 if( ter_bash.str_min != -1 && ( !ter_bash.bash_below || allow_floor ) ) {
2540 return ter_bash.str_min;
2541 }
2542
2543 return -1;
2544}
bool has_furn(const tripoint &p) const
Definition: map.cpp:1401
int str_min
Definition: mapdata.h:62

References bash(), map_data_common_t::bash, furn(), has_furn(), int_id< T >::obj(), map_bash_info::str_min, and ter().

Referenced by bash_resistance(), ranged::expected_coverage(), vehicle::part_collision(), rate_location(), smash(), and terrain_collision_data().

◆ bash_resistance() [2/2]

int map::bash_resistance ( point  p) const
inline

Definition at line 985 of file map.h.

985 {
986 return bash_resistance( tripoint( p, abs_sub.z ) );
987 }
int bash_resistance(const tripoint &p, bool allow_floor=false) const
Returns min_str of the furniture or terrain at p.
Definition: map.cpp:2532

References abs_sub, bash_resistance(), and tripoint::z.

◆ bash_strength() [1/2]

int map::bash_strength ( const tripoint p,
bool  allow_floor = false 
) const

Returns max_str of the furniture or terrain at p.

Definition at line 2518 of file map.cpp.

2519{
2520 if( has_furn( p ) && furn( p ).obj().bash.str_max != -1 ) {
2521 return furn( p ).obj().bash.str_max;
2522 }
2523
2524 const auto &ter_bash = ter( p ).obj().bash;
2525 if( ter_bash.str_max != -1 && ( !ter_bash.bash_below || allow_floor ) ) {
2526 return ter_bash.str_max;
2527 }
2528
2529 return -1;
2530}
int str_max
Definition: mapdata.h:64

References bash(), map_data_common_t::bash, furn(), has_furn(), int_id< T >::obj(), map_bash_info::str_max, and ter().

Referenced by bash_strength(), ranged::expected_coverage(), game::fling_creature(), and terrain_collision_data().

◆ bash_strength() [2/2]

int map::bash_strength ( point  p) const
inline

Definition at line 980 of file map.h.

980 {
981 return bash_strength( tripoint( p, abs_sub.z ) );
982 }
int bash_strength(const tripoint &p, bool allow_floor=false) const
Returns max_str of the furniture or terrain at p.
Definition: map.cpp:2518

References abs_sub, bash_strength(), and tripoint::z.

◆ bash_ter_furn()

bash_results map::bash_ter_furn ( const tripoint p,
const bash_params params 
)

Definition at line 3461 of file map.cpp.

3462{
3464 std::string soundfxvariant;
3465 const auto &ter_obj = ter( p ).obj();
3466 const auto &furn_obj = furn( p ).obj();
3467 bool smash_ter = false;
3468 const map_bash_info *bash = nullptr;
3469
3470 if( furn_obj.id && furn_obj.bash.str_max != -1 ) {
3471 bash = &furn_obj.bash;
3472 soundfxvariant = furn_obj.id.str();
3473 } else if( ter_obj.bash.str_max != -1 ) {
3474 bash = &ter_obj.bash;
3475 smash_ter = true;
3476 soundfxvariant = ter_obj.id.str();
3477 }
3478
3479 // Floor bashing check
3480 // Only allow bashing floors when we want to bash floors and we're in z-level mode
3481 // Unless we're destroying, then it gets a little weird
3482 if( smash_ter && bash->bash_below && ( !zlevels || !params.bash_floor ) ) {
3483 if( !params.destroy ) {
3484 smash_ter = false;
3485 bash = nullptr;
3486 } else if( !bash->ter_set && zlevels ) {
3487 // HACK: A hack for destroy && !bash_floor
3488 // We have to check what would we create and cancel if it is what we have now
3489 tripoint below( p.xy(), p.z - 1 );
3490 const auto roof = get_roof( below, false );
3491 if( roof == ter( p ) ) {
3492 smash_ter = false;
3493 bash = nullptr;
3494 }
3495 } else if( !bash->ter_set && ter( p ) == t_dirt ) {
3496 // As above, except for no-z-levels case
3497 smash_ter = false;
3498 bash = nullptr;
3499 }
3500 }
3501
3502 // TODO: what if silent is true?
3503 if( has_flag( "ALARMED", p ) && !g->timed_events.queued( TIMED_EVENT_WANTED ) ) {
3504 sounds::sound( p, 40, sounds::sound_t::alarm, _( "an alarm go off!" ),
3505 false, "environment", "alarm" );
3506 // Blame nearby player
3507 if( rl_dist( g->u.pos(), p ) <= 3 ) {
3508 g->events().send<event_type::triggers_alarm>( g->u.getID() );
3509 const point abs = ms_to_sm_copy( getabs( p.xy() ) );
3510 g->timed_events.add( TIMED_EVENT_WANTED, calendar::turn + 30_minutes, 0,
3511 tripoint( abs, p.z ) );
3512 }
3513 }
3514
3515 if( bash == nullptr || ( bash->destroy_only && !params.destroy ) ) {
3516 // Nothing bashable here
3517 if( impassable( p ) ) {
3518 if( !params.silent ) {
3519 sounds::sound( p, 18, sounds::sound_t::combat, _( "thump!" ),
3520 false, "smash_fail", "default" );
3521 }
3522
3523 result.did_bash = true;
3524 result.bashed_solid = true;
3525 }
3526
3527 return result;
3528 }
3529
3530 result.did_bash = true;
3531 result.bashed_solid = true;
3532 result.success = params.destroy;
3533
3534 int smin = bash->str_min;
3535 int smax = bash->str_max;
3536 if( !params.destroy ) {
3537 if( bash->str_min_blocked != -1 || bash->str_max_blocked != -1 ) {
3538 if( furn_is_supported( *this, p ) ) {
3539 if( bash->str_min_blocked != -1 ) {
3540 smin = bash->str_min_blocked;
3541 }
3542 if( bash->str_max_blocked != -1 ) {
3543 smax = bash->str_max_blocked;
3544 }
3545 }
3546 }
3547
3548 if( bash->str_min_supported != -1 || bash->str_max_supported != -1 ) {
3549 tripoint below( p.xy(), p.z - 1 );
3550 if( !zlevels || has_flag( TFLAG_SUPPORTS_ROOF, below ) ) {
3551 if( bash->str_min_supported != -1 ) {
3552 smin = bash->str_min_supported;
3553 }
3554 if( bash->str_max_supported != -1 ) {
3555 smax = bash->str_max_supported;
3556 }
3557 }
3558 }
3559 // Linear interpolation from str_min to str_max
3560 const int resistance = smin + ( params.roll * ( smax - smin ) );
3561 if( params.strength >= resistance ) {
3562 result.success = true;
3563 }
3564 }
3565
3566 if( !result.success ) {
3567 int sound_volume = bash->sound_fail_vol.value_or( 12 );
3568
3569 result.did_bash = true;
3570 if( !params.silent ) {
3571 sounds::sound( p, sound_volume, sounds::sound_t::combat, bash->sound_fail, false,
3572 "smash_fail", soundfxvariant );
3573 }
3574 } else {
3575 if( smash_ter ) {
3576 result |= bash_ter_success( p, params );
3577 } else {
3578 result |= bash_furn_success( p, params );
3579 }
3580 }
3581
3582 return result;
3583}
ter_id get_roof(const tripoint &p, bool allow_air) const
Definition: map.cpp:3163
bash_results bash_furn_success(const tripoint &p, const bash_params &params)
Definition: map.cpp:3361
bash_results bash_ter_success(const tripoint &p, const bash_params &params)
Definition: map.cpp:3231
point ms_to_sm_copy(point p)
static bool furn_is_supported(const map &m, const tripoint &p)
Definition: map.cpp:3207
ter_id t_dirt
Definition: mapdata.cpp:627
@ TFLAG_SUPPORTS_ROOF
Definition: mapdata.h:280
float roll
Value from 0.0 to 1.0 that affects interpolation between str_min and str_max At 0....
Definition: map.h:147
bool bash_floor
Definition: map.h:140
bool destroy
Definition: map.h:138
int strength
Definition: map.h:134
@ TIMED_EVENT_WANTED
Definition: timed_event.h:13

References _, sounds::alarm, bash(), bash_params::bash_floor, bash_furn_success(), bash_ter_success(), sounds::combat, bash_params::destroy, furn(), furn_is_supported(), g, get_roof(), getabs(), has_flag(), impassable(), ms_to_sm_copy(), int_id< T >::obj(), rl_dist(), bash_params::roll, bash_params::silent, sounds::sound(), bash_params::strength, t_dirt, ter(), TFLAG_SUPPORTS_ROOF, TIMED_EVENT_WANTED, triggers_alarm, calendar::turn, tripoint::xy(), tripoint::z, and zlevels.

Referenced by bash(), bash_ter_success(), and explosion_handler::do_blast_new().

◆ bash_ter_success()

bash_results map::bash_ter_success ( const tripoint p,
const bash_params params 
)

Definition at line 3231 of file map.cpp.

3232{
3234 result.success = true;
3235 const ter_t &ter_before = ter( p ).obj();
3236 const map_bash_info &bash = ter_before.bash;
3237 if( has_flag_ter( "FUNGUS", p ) ) {
3238 fungal_effects( *g, *this ).create_spores( p );
3239 }
3240 const std::string soundfxvariant = ter_before.id.str();
3241 const bool will_collapse = ter_before.has_flag( TFLAG_SUPPORTS_ROOF ) &&
3242 !ter_before.has_flag( TFLAG_INDOORS );
3243 const bool suspended = ter_before.has_flag( TFLAG_SUSPENDED );
3244 bool follow_below = false;
3245 if( params.bashing_from_above && bash.ter_set_bashed_from_above ) {
3246 // If this terrain is being bashed from above and this terrain
3247 // has a valid post-destroy bashed-from-above terrain, set it
3248 ter_set( p, bash.ter_set_bashed_from_above );
3249 } else if( bash.ter_set ) {
3250 // If the terrain has a valid post-destroy terrain, set it
3251 ter_set( p, bash.ter_set );
3252 follow_below |= zlevels && bash.bash_below;
3253 } else if( suspended ) {
3254 // Its important that we change the ter value before recursing, otherwise we'll hit an infinite loop.
3255 // This could be prevented by assembling a visited list, but in order to avoid that cost, we're going
3256 // build our recursion to just be resilient.
3257 ter_set( p, t_open_air );
3259 } else {
3260 tripoint below( p.xy(), p.z - 1 );
3261 const ter_t &ter_below = ter( below ).obj();
3262 // Only setting the flag here because we want drops and sounds in correct order
3263 follow_below |= zlevels && bash.bash_below && ter_below.roof;
3264
3265 ter_set( p, t_open_air );
3266 }
3267
3269
3270 if( !bash.sound.empty() && !params.silent ) {
3271 static const std::string soundfxid = "smash_success";
3272 int sound_volume = get_sound_volume( bash );
3273 sounds::sound( p, sound_volume, sounds::sound_t::combat, bash.sound, false,
3274 soundfxid, soundfxvariant );
3275 }
3276
3277 if( !zlevels ) {
3278 if( ter( p ) == t_open_air ) {
3279 // We destroyed something, so we aren't just "plugging" air with dirt here
3280 ter_set( p, t_dirt );
3281 }
3282 } else if( follow_below || ter( p ) == t_open_air ) {
3283 const tripoint below( p.xy(), p.z - 1 );
3284 // We may need multiple bashes in some weird cases
3285 // Example:
3286 // W has roof A
3287 // A bashes to B
3288 // B bashes to nothing
3289 // Below our point P, there is a W
3290 // If we bash down a B over a W, it might be from earlier A or just constructed over it!
3291 //
3292 // Current solution: bash roof until you reach same roof type twice, then bash down
3293 if( follow_below && params.do_recurse ) {
3294 bool blocked_by_roof = false;
3295 std::set<ter_id> encountered_types;
3296 encountered_types.insert( ter_before.id );
3297 encountered_types.insert( t_open_air );
3298 // Note: we're bashing the new roof, not the tile supported by it!
3299 int down_bash_tries = 10;
3300 do {
3301 const ter_id &ter_now = ter( p );
3302 if( encountered_types.count( ter_now ) != 0 ) {
3303 // We have encountered this type before and destroyed it (didn't block us)
3304 ter_set( p, t_open_air );
3305 bash_params params_below = params;
3306 params_below.bashing_from_above = true;
3307 params_below.bash_floor = false;
3308 params_below.do_recurse = false;
3309 params_below.destroy = true;
3310 int impassable_bash_tries = 10;
3311 // Unconditionally destroy, but don't go deeper
3312 do {
3313 result |= bash_ter_success( below, params_below );
3314 } while( ter( below )->movecost == 0 && impassable_bash_tries-- > 0 );
3315 if( impassable_bash_tries <= 0 ) {
3316 debugmsg( "Loop in terrain bashing for type %s", ter_before.id.str() );
3317 }
3318 } else if( ter_now == t_open_air ) {
3319 const ter_id &roof = get_roof( below, params.bash_floor && ter( below )->movecost != 0 );
3320 if( roof != t_open_air ) {
3321 ter_set( p, roof );
3322 }
3323 } else {
3324 // This floor/roof tile wasn't destroyed in this loop yet
3325 encountered_types.insert( ter_now );
3326 bash_params params_copy = params;
3327 params_copy.do_recurse = false;
3328 // TODO: Unwrap the calls, don't recurse
3329 // TODO: Don't bash furn
3330 bash_results results_sub = bash_ter_furn( p, params_copy );
3331 result |= results_sub;
3332 if( !results_sub.success ) {
3333 // Blocked, as in "the roof was too strong to bash"
3334 blocked_by_roof = true;
3335 }
3336 }
3337 } while( down_bash_tries-- > 0 && !blocked_by_roof &&
3338 ( ter( p ) != t_open_air || ter( p )->movecost == 0 || ter( below )->roof ) );
3339 if( down_bash_tries <= 0 ) {
3340 debugmsg( "Loop in terrain bashing for type %s", ter_before.id.str() );
3341 }
3342 } else {
3343 const ter_id &roof = get_roof( below, params.bash_floor && ter( below )->movecost != 0 );
3344
3345 ter_set( p, roof );
3346 }
3347 }
3348
3349 if( will_collapse && !has_flag( TFLAG_SUPPORTS_ROOF, p ) ) {
3350 collapse_at( p, params.silent, true, bash.explosive > 0 );
3351 }
3352
3353 if( bash.explosive > 0 ) {
3354 // TODO Implement if the player triggered the explosive terrain
3355 explosion_handler::explosion( p, nullptr, bash.explosive, 0.8, false );
3356 }
3357
3358 return result;
3359}
void propagate_suspension_check(const tripoint &point)
Checks surrounding tiles for suspension, and has them check for collapse.
Definition: map.cpp:3012
void collapse_at(const tripoint &p, bool silent, bool was_supporting=false, bool destroy_pos=true)
Causes a collapse at p, such as from destroying a wall.
Definition: map.cpp:2967
const std::string & str() const
Returns the identifier as plain std::string.
Definition: string_id.h:255
@ TFLAG_SUSPENDED
Definition: mapdata.h:323
@ TFLAG_INDOORS
Definition: mapdata.h:291
bool do_recurse
Hack to prevent infinite recursion.
Definition: map.h:159
bool bashing_from_above
Definition: map.h:154
bool success
Definition: map.h:170
bool has_flag(const std::string &flag) const
Definition: mapdata.h:419
ter_str_id id
Definition: mapdata.h:465

References bash(), map_data_common_t::bash, bash_params::bash_floor, bash_ter_furn(), bash_ter_success(), bash_params::bashing_from_above, collapse_at(), sounds::combat, fungal_effects::create_spores(), debugmsg, bash_params::destroy, bash_params::do_recurse, explosion_handler::explosion(), g, get_roof(), get_sound_volume(), map_data_common_t::has_flag(), has_flag(), has_flag_ter(), ter_t::id, item_group::items_from(), int_id< T >::obj(), propagate_suspension_check(), ter_t::roof, bash_params::silent, sounds::sound(), spawn_items(), string_id< T >::str(), bash_results::success, t_dirt, t_open_air, ter(), ter_set(), TFLAG_INDOORS, TFLAG_SUPPORTS_ROOF, TFLAG_SUSPENDED, calendar::turn, tripoint::xy(), tripoint::z, and zlevels.

Referenced by bash_ter_furn(), bash_ter_success(), and shoot().

◆ bash_vehicle()

bash_results map::bash_vehicle ( const tripoint p,
const bash_params params 
)

Definition at line 3657 of file map.cpp.

3658{
3660 // Smash vehicle if present
3661 if( const optional_vpart_position vp = veh_at( p ) ) {
3662 vp->vehicle().damage( vp->part_index(), params.strength, DT_BASH );
3663 if( !params.silent ) {
3664 sounds::sound( p, 18, sounds::sound_t::combat, _( "crash!" ), false,
3665 "smash_success", "hit_vehicle" );
3666 }
3667
3668 result.did_bash = true;
3669 result.success = true;
3670 result.bashed_solid = true;
3671 }
3672 return result;
3673}
@ DT_BASH
Definition: damage.h:24

References _, sounds::combat, DT_BASH, bash_params::silent, sounds::sound(), bash_params::strength, and veh_at().

Referenced by bash().

◆ batter()

void map::batter ( const tripoint p,
int  power,
int  tries = 1,
bool  silent = false 
)

bash a square for a set number of times at set power.

Does not destroy

Definition at line 3722 of file map.cpp.

3723{
3724 int count = 0;
3725 while( count < tries && bash( p, power, silent ).success ) {
3726 count++;
3727 }
3728}
@ success
Definition: behavior.h:20

References bash(), detail::count(), silent, and behavior::success.

Referenced by activity_handlers::chop_tree_finish().

◆ board_vehicle()

void map::board_vehicle ( const tripoint p,
player pl 
)

Definition at line 1107 of file map.cpp.

1108{
1109 if( p == nullptr ) {
1110 debugmsg( "map::board_vehicle: null player" );
1111 return;
1112 }
1113
1115 true );
1116 if( !vp ) {
1117 if( p->grab_point.x == 0 && p->grab_point.y == 0 ) {
1118 debugmsg( "map::board_vehicle: vehicle not found" );
1119 }
1120 return;
1121 }
1122 if( vp->part().has_flag( vehicle_part::passenger_flag ) ) {
1123 player *psg = vp->vehicle().get_passenger( vp->part_index() );
1124 debugmsg( "map::board_vehicle: passenger (%s) is already there",
1125 psg ? psg->name : "<null>" );
1126 unboard_vehicle( pos );
1127 }
1128 vp->part().set_flag( vehicle_part::passenger_flag );
1129 vp->part().passenger_id = p->getID();
1130 vp->vehicle().invalidate_mass();
1131
1132 p->setpos( pos );
1133 p->in_vehicle = true;
1134 if( p->is_avatar() ) {
1135 g->update_map( g->u );
1136 }
1137}
std::string name
Definition: character.h:1529
void unboard_vehicle(const vpart_reference &, Character *passenger, bool dead_passenger=false)
Definition: map.cpp:1139
cata::optional< vpart_reference > part_with_feature(const std::string &f, bool unbroken) const
Definition: vehicle.cpp:2482
Definition: player.h:84
@ passenger_flag
Definition: vehicle.h:193
@ VPFLAG_BOARDABLE
Definition: veh_type.h:39

References debugmsg, g, Character::getID(), player::grab_point, Character::in_vehicle, Creature::is_avatar(), Character::name, optional_vpart_position::part_with_feature(), vehicle_part::passenger_flag, wrapped_vehicle::pos, Character::setpos(), unboard_vehicle(), veh_at(), VPFLAG_BOARDABLE, tripoint::x, and tripoint::y.

Referenced by debug_menu::debug(), npc::move_to(), game::phasing_move(), game::place_player(), game::swap_critters(), and avatar_action::swim().

◆ build_floor_cache()

bool map::build_floor_cache ( int  zlev)

Definition at line 8076 of file map.cpp.

8077{
8078 auto &ch = get_cache( zlev );
8079 if( !ch.floor_cache_dirty ) {
8080 return false;
8081 }
8082
8083 auto &floor_cache = ch.floor_cache;
8084 std::uninitialized_fill_n(
8085 &floor_cache[0][0], ( MAPSIZE_X ) * ( MAPSIZE_Y ), true );
8086
8087 bool lowest_z_lev = zlev <= -OVERMAP_DEPTH;
8088 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
8089 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
8090 const submap *cur_submap = get_submap_at_grid( { smx, smy, zlev } );
8091 const submap *below_submap = !lowest_z_lev ? get_submap_at_grid( { smx, smy, zlev - 1 } ) : nullptr;
8092
8093 if( cur_submap == nullptr ) {
8094 debugmsg( "Tried to build floor cache at (%d,%d,%d) but the submap is not loaded", smx, smy, zlev );
8095 continue;
8096 }
8097 if( !lowest_z_lev && below_submap == nullptr ) {
8098 debugmsg( "Tried to build floor cache at (%d,%d,%d) but the submap is not loaded", smx, smy,
8099 zlev - 1 );
8100 continue;
8101 }
8102
8103 for( int sx = 0; sx < SEEX; ++sx ) {
8104 for( int sy = 0; sy < SEEY; ++sy ) {
8105 point sp( sx, sy );
8106 const ter_t &terrain = cur_submap->get_ter( sp ).obj();
8107 if( terrain.has_flag( TFLAG_NO_FLOOR ) ) {
8108 if( below_submap && ( below_submap->get_furn( sp ).obj().has_flag( TFLAG_SUN_ROOF_ABOVE ) ) ) {
8109 continue;
8110 }
8111 const int x = sx + smx * SEEX;
8112 const int y = sy + smy * SEEY;
8113 floor_cache[x][y] = false;
8114 }
8115 }
8116 }
8117 }
8118 }
8119
8120 ch.floor_cache_dirty = false;
8121 return zlevels;
8122}
@ TFLAG_SUN_ROOF_ABOVE
Definition: mapdata.h:322
@ TFLAG_NO_FLOOR
Definition: mapdata.h:310
static const int sx[4]
Definition: tileray.cpp:10
static const int sy[4]
Definition: tileray.cpp:11

References debugmsg, get_cache(), get_submap_at_grid(), submap::get_ter(), MAPSIZE_X, MAPSIZE_Y, my_MAPSIZE, int_id< T >::obj(), OVERMAP_DEPTH, SEEX, SEEY, sx, sy, terrain, TFLAG_NO_FLOOR, TFLAG_SUN_ROOF_ABOVE, and zlevels.

Referenced by build_floor_caches(), and build_map_cache().

◆ build_floor_caches()

void map::build_floor_caches ( )

Definition at line 8124 of file map.cpp.

8125{
8126 const int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
8127 const int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
8128 for( int z = minz; z <= maxz; z++ ) {
8129 build_floor_cache( z );
8130 }
8131}
bool build_floor_cache(int zlev)
Definition: map.cpp:8076

References abs_sub, build_floor_cache(), OVERMAP_DEPTH, OVERMAP_HEIGHT, tripoint::z, and zlevels.

Referenced by game::do_turn().

◆ build_map_cache()

void map::build_map_cache ( int  zlev,
bool  skip_lightmap = false 
)

Definition at line 8290 of file map.cpp.

8291{
8292 const int minz = zlevels ? -OVERMAP_DEPTH : zlev;
8293 const int maxz = zlevels ? OVERMAP_HEIGHT : zlev;
8294 bool seen_cache_dirty = false;
8295 for( int z = minz; z <= maxz; z++ ) {
8296 // trigger FOV recalculation only when there is a change on the player's level or if fov_3d is enabled
8297 const bool affects_seen_cache = z == zlev || fov_3d;
8301 seen_cache_dirty |= ( build_floor_cache( z ) && affects_seen_cache );
8302 seen_cache_dirty |= get_cache( z ).seen_cache_dirty && affects_seen_cache;
8303 diagonal_blocks fill = {false, false};
8304 std::uninitialized_fill_n( &( get_cache( z ).vehicle_obscured_cache[0][0] ), MAPSIZE_X * MAPSIZE_Y,
8305 fill );
8306 std::uninitialized_fill_n( &( get_cache( z ).vehicle_obstructed_cache[0][0] ),
8308 }
8309 // needs a separate pass as it changes the caches on neighbour z-levels (e.g. floor_cache);
8310 // otherwise such changes might be overwritten by main cache-building logic
8311 for( int z = minz; z <= maxz; z++ ) {
8312 do_vehicle_caching( z );
8313 }
8314
8316
8317 if( seen_cache_dirty ) {
8318 skew_vision_cache.clear();
8319 }
8320 // Initial value is illegal player position.
8321 const tripoint &p = g->u.pos();
8322 static tripoint player_prev_pos;
8323 if( seen_cache_dirty || player_prev_pos != p ) {
8324 build_seen_cache( p, zlev );
8325 player_prev_pos = p;
8326 }
8327 if( !skip_lightmap ) {
8328 generate_lightmap( zlev );
8329 }
8330}
bool fov_3d
3D FoV enabled/disabled.
void build_outside_cache(int zlev)
Definition: map.cpp:7969
void update_suspension_cache(const int &z)
Definition: map.cpp:8133
void do_vehicle_caching(int z)
Definition: map.cpp:8273
void build_seen_cache(const tripoint &origin, int target_z)
Calculates the Field Of View for the provided map from the given x, y coordinates.
Definition: lightmap.cpp:1392
lru_cache< point, char > skew_vision_cache
Cache of coordinate pairs recently checked for visibility.
Definition: map.h:1967
bool build_transparency_cache(int zlev)
Definition: lightmap.cpp:82
void generate_lightmap(int zlev)
Definition: lightmap.cpp:400
bool build_vision_transparency_cache(const Character &player)
Definition: lightmap.cpp:168
FMT_NOINLINE OutputIt fill(OutputIt it, size_t n, const fill_t< Char > &fill)
bool seen_cache_dirty
Definition: map.h:309

References build_floor_cache(), build_outside_cache(), build_seen_cache(), build_transparency_cache(), build_vision_transparency_cache(), do_vehicle_caching(), detail::fill(), fov_3d, g, generate_lightmap(), get_cache(), get_player_character(), MAPSIZE_X, MAPSIZE_Y, OVERMAP_DEPTH, OVERMAP_HEIGHT, level_cache::seen_cache_dirty, skew_vision_cache, update_suspension_cache(), and zlevels.

Referenced by game::do_turn(), game::draw(), game::look_around(), start_location::place_player(), game::start_game(), and game::update_map().

◆ build_obstacle_cache()

void map::build_obstacle_cache ( const tripoint start,
const tripoint end,
float(&)  obstacle_cache[MAPSIZE_X][MAPSIZE_Y] 
)

Definition at line 8023 of file map.cpp.

8025{
8026 const point min_submap{ std::max( 0, start.x / SEEX ), std::max( 0, start.y / SEEY ) };
8027 const point max_submap{
8028 std::min( my_MAPSIZE - 1, end.x / SEEX ), std::min( my_MAPSIZE - 1, end.y / SEEY ) };
8029 // Find and cache all the map obstacles.
8030 // For now setting obstacles to be extremely dense and fill their squares.
8031 // In future, scale effective obstacle density by the thickness of the obstacle.
8032 // Also consider modelling partial obstacles.
8033 // TODO: Support z-levels.
8034 for( int smx = min_submap.x; smx <= max_submap.x; ++smx ) {
8035 for( int smy = min_submap.y; smy <= max_submap.y; ++smy ) {
8036 const auto cur_submap = get_submap_at_grid( { smx, smy, start.z } );
8037
8038 // TODO: Init indices to prevent iterating over unused submap sections.
8039 for( int sx = 0; sx < SEEX; ++sx ) {
8040 for( int sy = 0; sy < SEEY; ++sy ) {
8041 const point sp( sx, sy );
8042 int ter_move = cur_submap->get_ter( sp ).obj().movecost;
8043 int furn_move = cur_submap->get_furn( sp ).obj().movecost;
8044 const int x = sx + smx * SEEX;
8045 const int y = sy + smy * SEEY;
8046 if( ter_move == 0 || furn_move < 0 || ter_move + furn_move == 0 ) {
8047 obstacle_cache[x][y] = 1000.0f;
8048 } else {
8049 obstacle_cache[x][y] = 0.0f;
8050 }
8051 }
8052 }
8053 }
8054 }
8055 VehicleList vehs = get_vehicles( start, end );
8056 const inclusive_cuboid<tripoint> bounds( start, end );
8057 // Cache all the vehicle stuff in one loop
8058 for( auto &v : vehs ) {
8059 for( const vpart_reference &vp : v.v->get_all_parts() ) {
8060 tripoint p = v.pos + vp.part().precalc[0];
8061 if( p.z != start.z ) {
8062 break;
8063 }
8064 if( !bounds.contains( p ) ) {
8065 continue;
8066 }
8067
8068 if( vp.obstacle_at_part() ) {
8069 obstacle_cache[p.x][p.y] = 1000.0f;
8070 }
8071 }
8072 }
8073
8074}
VehicleList get_vehicles()
Definition: map.cpp:295
std::vector< wrapped_vehicle > VehicleList
Definition: map.h:85

References inclusive_cuboid< Tripoint, >::contains(), get_submap_at_grid(), get_vehicles(), my_MAPSIZE, SEEX, SEEY, sx, sy, tripoint::x, tripoint::y, and tripoint::z.

Referenced by explosion_handler::shrapnel().

◆ build_outside_cache()

void map::build_outside_cache ( int  zlev)

Definition at line 7969 of file map.cpp.

7970{
7971 auto &ch = get_cache( zlev );
7972 if( !ch.outside_cache_dirty ) {
7973 return;
7974 }
7975
7976 // Make a bigger cache to avoid bounds checking
7977 // We will later copy it to our regular cache
7978 const size_t padded_w = ( MAPSIZE_X ) + 2;
7979 const size_t padded_h = ( MAPSIZE_Y ) + 2;
7980 bool padded_cache[padded_w][padded_h];
7981
7982 auto &outside_cache = ch.outside_cache;
7983 if( zlev < 0 ) {
7984 std::uninitialized_fill_n(
7985 &outside_cache[0][0], ( MAPSIZE_X ) * ( MAPSIZE_Y ), false );
7986 return;
7987 }
7988
7989 std::uninitialized_fill_n(
7990 &padded_cache[0][0], padded_w * padded_h, true );
7991
7992 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
7993 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
7994 const auto cur_submap = get_submap_at_grid( { smx, smy, zlev } );
7995
7996 for( int sx = 0; sx < SEEX; ++sx ) {
7997 for( int sy = 0; sy < SEEY; ++sy ) {
7998 point sp( sx, sy );
7999 if( cur_submap->get_ter( sp ).obj().has_flag( TFLAG_INDOORS ) ||
8000 cur_submap->get_furn( sp ).obj().has_flag( TFLAG_INDOORS ) ) {
8001 const int x = sx + smx * SEEX;
8002 const int y = sy + smy * SEEY;
8003 // Add 1 to both coordinates, because we're operating on the padded cache
8004 for( int dx = 0; dx <= 2; dx++ ) {
8005 for( int dy = 0; dy <= 2; dy++ ) {
8006 padded_cache[x + dx][y + dy] = false;
8007 }
8008 }
8009 }
8010 }
8011 }
8012 }
8013 }
8014
8015 // Copy the padded cache back to the proper one, but with no padding
8016 for( int x = 0; x < SEEX * my_MAPSIZE; x++ ) {
8017 std::copy_n( &padded_cache[x + 1][1], SEEX * my_MAPSIZE, &outside_cache[x][0] );
8018 }
8019
8020 ch.outside_cache_dirty = false;
8021}

References get_cache(), get_submap_at_grid(), MAPSIZE_X, MAPSIZE_Y, my_MAPSIZE, SEEX, SEEY, sx, sy, and TFLAG_INDOORS.

Referenced by build_map_cache(), start_location::burn(), and start_location::prepare_map().

◆ build_seen_cache()

void map::build_seen_cache ( const tripoint origin,
int  target_z 
)
protected

Calculates the Field Of View for the provided map from the given x, y coordinates.

Returns a lightmap for a result where the values represent a percentage of fully lit.

A value equal to or below 0 means that cell is not in the field of view, whereas a value equal to or above 1 means that cell is in the field of view.

Parameters
originthe starting location
target_zZ-level to draw light map on

Definition at line 1392 of file lightmap.cpp.

1393{
1394 auto &map_cache = get_cache( target_z );
1395 float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.transparency_cache;
1396 float ( &seen_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.seen_cache;
1397 float ( &camera_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.camera_cache;
1398 diagonal_blocks( &blocked_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.vehicle_obscured_cache;
1399
1400 constexpr float light_transparency_solid = LIGHT_TRANSPARENCY_SOLID;
1401 constexpr int map_dimensions = MAPSIZE_X * MAPSIZE_Y;
1402 std::uninitialized_fill_n(
1403 &camera_cache[0][0], map_dimensions, light_transparency_solid );
1404
1405 float vision_restore_cache [9] = {0};
1406 bool blocked_restore_cache[8] = {false};
1407
1408 if( origin.z == target_z ) {
1409 apply_vision_transparency_cache( get_player_character().pos(), target_z, vision_restore_cache,
1410 blocked_restore_cache );
1411 }
1412
1413 if( !fov_3d ) {
1414 for( int z = -OVERMAP_DEPTH; z <= OVERMAP_HEIGHT; z++ ) {
1415 auto &cur_cache = get_cache( z );
1416 if( z == target_z || cur_cache.seen_cache_dirty ) {
1417 std::uninitialized_fill_n(
1418 &cur_cache.seen_cache[0][0], map_dimensions, light_transparency_solid );
1419 cur_cache.seen_cache_dirty = false;
1420 }
1421
1422 if( z == target_z ) {
1423 seen_cache[origin.x][origin.y] = VISIBILITY_FULL;
1424 castLightAll<float, float, sight_calc, sight_check, update_light, accumulate_transparency>(
1425 seen_cache, transparency_cache, blocked_cache, origin.xy(), 0 );
1426 }
1427 }
1428 } else {
1429 // Cache the caches (pointers to them)
1430 array_of_grids_of<const float> transparency_caches;
1431 array_of_grids_of<float> seen_caches;
1432 array_of_grids_of<const bool> floor_caches;
1434 for( int z = -OVERMAP_DEPTH; z <= OVERMAP_HEIGHT; z++ ) {
1435 auto &cur_cache = get_cache( z );
1436 transparency_caches[z + OVERMAP_DEPTH] = &cur_cache.transparency_cache;
1437 seen_caches[z + OVERMAP_DEPTH] = &cur_cache.seen_cache;
1438 floor_caches[z + OVERMAP_DEPTH] = &cur_cache.floor_cache;
1439 blocked_caches[z + OVERMAP_DEPTH] = &cur_cache.vehicle_obscured_cache;
1440 std::uninitialized_fill_n(
1441 &cur_cache.seen_cache[0][0], map_dimensions, light_transparency_solid );
1442 cur_cache.seen_cache_dirty = false;
1443 }
1444 if( origin.z == target_z ) {
1446 }
1448 seen_caches, transparency_caches, floor_caches, blocked_caches, origin, 0, 1.0 );
1449 }
1450
1451 if( origin.z == target_z ) {
1452 restore_vision_transparency_cache( get_player_character().pos(), target_z, vision_restore_cache,
1453 blocked_restore_cache );
1454 }
1455
1457 if( !vp ) {
1458 return;
1459 }
1460 vehicle *const veh = &vp->vehicle();
1461
1462 // We're inside a vehicle. Do mirror calculations.
1463 std::vector<int> mirrors;
1464 // Do all the sight checks first to prevent fake multiple reflection
1465 // from happening due to mirrors becoming visible due to processing order.
1466 // Cameras are also handled here, so that we only need to get through all vehicle parts once
1467 int cam_control = -1;
1468 for( const vpart_reference &vp : veh->get_avail_parts( VPFLAG_EXTENDS_VISION ) ) {
1469 const tripoint mirror_pos = vp.pos();
1470 // We can utilize the current state of the seen cache to determine
1471 // if the player can see the mirror from their position.
1472 if( !vp.info().has_flag( "CAMERA" ) &&
1473 seen_cache[mirror_pos.x][mirror_pos.y] < LIGHT_TRANSPARENCY_SOLID + 0.1 ) {
1474 continue;
1475 } else if( !vp.info().has_flag( "CAMERA_CONTROL" ) ) {
1476 mirrors.emplace_back( static_cast<int>( vp.part_index() ) );
1477 } else {
1478 if( square_dist( origin, mirror_pos ) <= 1 && veh->camera_on ) {
1479 cam_control = static_cast<int>( vp.part_index() );
1480 }
1481 }
1482 }
1483
1484 for( int mirror : mirrors ) {
1485 bool is_camera = veh->part_info( mirror ).has_flag( "CAMERA" );
1486 if( is_camera && cam_control < 0 ) {
1487 continue; // Player not at camera control, so cameras don't work
1488 }
1489
1490 const tripoint mirror_pos = veh->global_part_pos3( mirror );
1491
1492 // Determine how far the light has already traveled so mirrors
1493 // don't cheat the light distance falloff.
1494 int offsetDistance;
1495 if( !is_camera ) {
1496 offsetDistance = rl_dist( origin, mirror_pos );
1497 } else {
1498 offsetDistance = 60 - veh->part_info( mirror ).bonus *
1499 veh->part( mirror ).hp() / veh->part_info( mirror ).durability;
1500 camera_cache[mirror_pos.x][mirror_pos.y] = LIGHT_TRANSPARENCY_OPEN_AIR;
1501 }
1502
1503 // TODO: Factor in the mirror facing and only cast in the
1504 // directions the player's line of sight reflects to.
1505 //
1506 // The naive solution of making the mirrors act like a second player
1507 // at an offset appears to give reasonable results though.
1508 castLightAll<float, float, sight_calc, sight_check, update_light, accumulate_transparency>(
1509 camera_cache, transparency_cache, blocked_cache, mirror_pos.xy(), offsetDistance );
1510 }
1511}
void restore_vision_transparency_cache(const tripoint &center, int target_z, float(&vision_restore_cache)[9], bool(&blocked_restore_cache)[8])
Definition: lightmap.cpp:1352
void apply_vision_transparency_cache(const tripoint &center, int target_z, float(&vision_restore_cache)[9], bool(&blocked_restore_cache)[8])
Definition: lightmap.cpp:1313
vehicle_part_with_feature_range< std::string > get_avail_parts(std::string feature) const
Yields a range of parts of this vehicle that each have the given feature and are available: not broke...
Definition: vehicle.cpp:2715
bool camera_on
Definition: vehicle.h:2021
const vpart_info & part_info(int index, bool include_removed=false) const
Definition: vehicle.cpp:1138
int bonus
seatbelt (str), muffler (%), horn (vol), light (intensity), recharing (power)
Definition: veh_type.h:269
bool has_flag(const std::string &flag) const
Definition: veh_type.h:336
int durability
Maximum damage part can sustain before being destroyed.
Definition: veh_type.h:173
template void cast_zlight< float, sight_calc, sight_check, accumulate_transparency >(const array_of_grids_of< float > &output_caches, const array_of_grids_of< const float > &input_arrays, const array_of_grids_of< const bool > &floor_caches, const array_of_grids_of< const diagonal_blocks > &blocked_caches, const tripoint &origin, int offset_distance, float numerator)
static constexpr float VISIBILITY_FULL
Definition: lightmap.h:39
std::array< T(*)[MAPSIZE_X][MAPSIZE_Y], OVERMAP_LAYERS > array_of_grids_of
int hp() const
current part health with range [0,durability]
@ VPFLAG_EXTENDS_VISION
Definition: veh_type.h:68

References apply_vision_transparency_cache(), vpart_info::bonus, vehicle::camera_on, cast_zlight< float, sight_calc, sight_check, accumulate_transparency >(), vpart_info::durability, fov_3d, vehicle::get_avail_parts(), get_cache(), get_player_character(), vehicle::global_part_pos3(), vpart_info::has_flag(), vehicle_part::hp(), LIGHT_TRANSPARENCY_OPEN_AIR, LIGHT_TRANSPARENCY_SOLID, MAPSIZE_X, MAPSIZE_Y, OVERMAP_DEPTH, OVERMAP_HEIGHT, vehicle::part(), vehicle::part_info(), restore_vision_transparency_cache(), rl_dist(), level_cache::seen_cache, square_dist(), veh_at(), VISIBILITY_FULL, VPFLAG_EXTENDS_VISION, tripoint::x, tripoint::xy(), and tripoint::y.

Referenced by build_map_cache().

◆ build_sunlight_cache()

void map::build_sunlight_cache ( int  pzlev)
protected

Definition at line 249 of file lightmap.cpp.

250{
251 const int zlev_min = zlevels ? -OVERMAP_DEPTH : pzlev;
252 // Start at the topmost populated zlevel to avoid unnecessary raycasting
253 // Plus one zlevel to prevent clipping inside structures
254 const int zlev_max = zlevels
256 std::min( OVERMAP_HEIGHT, pzlev + 1 ),
258 : pzlev;
259
260 // true if all previous z-levels are fully transparent to light (no floors, transparency >= air)
261 bool fully_outside = true;
262
263 // true if no light reaches this level, i.e. there were no lit tiles on the above level (light level <= inside_light_level)
264 bool fully_inside = false;
265
266 // fully_outside and fully_inside define following states:
267 // initially: fully_outside=true, fully_inside=false (fast fill)
268 // ↓
269 // when first obstacles occur: fully_outside=false, fully_inside=false (slow quadrant logic)
270 // ↓
271 // when fully below ground: fully_outside=false, fully_inside=true (fast fill)
272
273 // Iterate top to bottom because sunlight cache needs to construct in that order.
274 for( int zlev = zlev_max; zlev >= zlev_min; zlev-- ) {
275
276 level_cache &map_cache = get_cache( zlev );
277 auto &lm = map_cache.lm;
278 // Grab illumination at ground level.
279 const float outside_light_level = g->natural_light_level( 0 );
280 // TODO: if zlev < 0 is open to sunlight, this won't calculate correct light, but neither does g->natural_light_level()
281 const float inside_light_level = ( zlev >= 0 && outside_light_level > LIGHT_SOURCE_BRIGHT ) ?
283 // Handling when z-levels are disabled is based on whether a tile is considered "outside".
284 if( !zlevels ) {
285 const auto &outside_cache = map_cache.outside_cache;
286 for( int x = 0; x < MAPSIZE_X; x++ ) {
287 for( int y = 0; y < MAPSIZE_Y; y++ ) {
288 if( outside_cache[x][y] ) {
289 lm[x][y].fill( outside_light_level );
290 } else {
291 lm[x][y].fill( inside_light_level );
292 }
293 }
294 }
295 continue;
296 }
297
298 // all light was blocked before
299 if( fully_inside ) {
300 std::fill_n( &lm[0][0], MAPSIZE_X * MAPSIZE_Y, four_quadrants( inside_light_level ) );
301 continue;
302 }
303
304 // If there were no obstacles before this level, just apply weather illumination since there's no opportunity
305 // for light to be blocked.
306 if( fully_outside ) {
307 //fill with full light
308 std::fill_n( &lm[0][0], MAPSIZE_X * MAPSIZE_Y, four_quadrants( outside_light_level ) );
309
310 const auto &this_floor_cache = map_cache.floor_cache;
311 const auto &this_transparency_cache = map_cache.transparency_cache;
312 fully_inside = true; // recalculate
313
314 for( int x = 0; x < MAPSIZE_X; ++x ) {
315 for( int y = 0; y < MAPSIZE_Y; ++y ) {
316 // && semantics below is important, we want to skip the evaluation if possible, do not replace with &=
317
318 // fully_outside stays true if tile is transparent and there is no floor
319 fully_outside = fully_outside && this_transparency_cache[x][y] >= LIGHT_TRANSPARENCY_OPEN_AIR
320 && !this_floor_cache[x][y];
321 // fully_inside stays true if tile is opaque OR there is floor
322 fully_inside = fully_inside && ( this_transparency_cache[x][y] <= LIGHT_TRANSPARENCY_SOLID ||
323 this_floor_cache[x][y] );
324 }
325 }
326 continue;
327 }
328
329 // Replace this with a calculated shift based on time of day and date.
330 // At first compress the angle such that it takes no more than one tile of shift per level.
331 // To exceed that, we'll have to handle casting light from the side instead of the top.
332 point offset;
333 const level_cache &prev_map_cache = get_cache_ref( zlev + 1 );
334 const auto &prev_lm = prev_map_cache.lm;
335 const auto &prev_transparency_cache = prev_map_cache.transparency_cache;
336 const auto &prev_floor_cache = prev_map_cache.floor_cache;
337 const auto &outside_cache = map_cache.outside_cache;
338 const float sight_penalty = get_weather().weather_id->sight_penalty;
339 // TODO: Replace these with a lookup inside the four_quadrants class.
340 constexpr std::array<point, 5> cardinals = {
342 };
343 constexpr std::array<std::array<quadrant, 2>, 5> dir_quadrants = {{
349 }
350 };
351
352 fully_inside = true; // recalculate
353
354 // Fall back to minimal light level if we don't find anything.
355 std::fill_n( &lm[0][0], MAPSIZE_X * MAPSIZE_Y, four_quadrants( inside_light_level ) );
356
357 for( int x = 0; x < MAPSIZE_X; ++x ) {
358 for( int y = 0; y < MAPSIZE_Y; ++y ) {
359 // Check center, then four adjacent cardinals.
360 for( int i = 0; i < 5; ++i ) {
361 int prev_x = x + offset.x + cardinals[i].x;
362 int prev_y = y + offset.y + cardinals[i].y;
363 bool inbounds = prev_x >= 0 && prev_x < MAPSIZE_X &&
364 prev_y >= 0 && prev_y < MAPSIZE_Y;
365
366 if( !inbounds ) {
367 continue;
368 }
369
370 float prev_light_max;
371 float prev_transparency = prev_transparency_cache[prev_x][prev_y];
372 // This is pretty gross, this cancels out the per-tile transparency effect
373 // derived from weather.
374 if( outside_cache[x][y] ) {
375 prev_transparency /= sight_penalty;
376 }
377
378 if( prev_transparency > LIGHT_TRANSPARENCY_SOLID &&
379 !prev_floor_cache[prev_x][prev_y] &&
380 ( prev_light_max = prev_lm[prev_x][prev_y].max() ) > 0.0 ) {
381 const float light_level = clamp( prev_light_max * LIGHT_TRANSPARENCY_OPEN_AIR / prev_transparency,
382 inside_light_level, prev_light_max );
383
384 if( i == 0 ) {
385 lm[x][y].fill( light_level );
386 fully_inside &= light_level <= inside_light_level;
387 break;
388 } else {
389 fully_inside &= light_level <= inside_light_level;
390 lm[x][y][dir_quadrants[i][0]] = light_level;
391 lm[x][y][dir_quadrants[i][1]] = light_level;
392 }
393 }
394 }
395 }
396 }
397 }
398}
constexpr T clamp(const T &val, const T &min, const T &max)
Clamp first argument so that it is no lower than second and no higher than third.
Definition: cata_utility.h:145
int calc_max_populated_zlev()
Caclulate the greatest populated zlevel in the loaded submaps and save in the level cache.
Definition: map.cpp:9062
weather_type_id weather_id
Definition: weather.h:193
weather_manager & get_weather()
Definition: weather.cpp:64
static constexpr float LIGHT_AMBIENT_DIM
Definition: lightmap.h:16
bool floor_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:328
bool outside_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:322
float sight_penalty
Definition: weather_type.h:111

References calc_max_populated_zlev(), clamp(), level_cache::floor_cache, g, get_cache(), get_cache_ref(), get_weather(), inbounds(), LIGHT_AMBIENT_DIM, LIGHT_AMBIENT_LOW, LIGHT_SOURCE_BRIGHT, LIGHT_TRANSPARENCY_OPEN_AIR, LIGHT_TRANSPARENCY_SOLID, level_cache::lm, MAPSIZE_X, MAPSIZE_Y, NE, NW, level_cache::outside_cache, OVERMAP_DEPTH, OVERMAP_HEIGHT, point_east, point_north, point_south, point_west, point_zero, SE, weather_type::sight_penalty, SW, level_cache::transparency_cache, weather_manager::weather_id, point::x, point::y, and zlevels.

Referenced by generate_lightmap().

◆ build_transparency_cache()

bool map::build_transparency_cache ( int  zlev)
protected

Definition at line 82 of file lightmap.cpp.

83{
84 auto &map_cache = get_cache( zlev );
85 auto &transparency_cache = map_cache.transparency_cache;
86 auto &outside_cache = map_cache.outside_cache;
87
88 if( map_cache.transparency_cache_dirty.none() ) {
89 return false;
90 }
91
92 std::set<tripoint> vehicles_processed;
93
94 // if true, all submaps are invalid (can use batch init)
95 bool rebuild_all = map_cache.transparency_cache_dirty.all();
96
97 if( rebuild_all ) {
98 // Default to just barely not transparent.
99 std::uninitialized_fill_n( &transparency_cache[0][0], MAPSIZE_X * MAPSIZE_Y,
100 static_cast<float>( LIGHT_TRANSPARENCY_OPEN_AIR ) );
101 }
102
103 const float sight_penalty = get_weather().weather_id->sight_penalty;
104
105 // Traverse the submaps in order
106 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
107 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
108 const auto cur_submap = get_submap_at_grid( {smx, smy, zlev} );
109
110 const point sm_offset = sm_to_ms_copy( point( smx, smy ) );
111
112 if( !rebuild_all && !map_cache.transparency_cache_dirty[smx * MAPSIZE + smy] ) {
113 continue;
114 }
115
116 // calculates transparency of a single tile
117 // x,y - coords in map local coords
118 auto calc_transp = [&]( point p ) {
119 const point sp = p - sm_offset;
120 float value = LIGHT_TRANSPARENCY_OPEN_AIR;
121
122 if( !( cur_submap->get_ter( sp ).obj().transparent &&
123 cur_submap->get_furn( sp ).obj().transparent ) ) {
125 }
126 if( outside_cache[p.x][p.y] ) {
127 // FIXME: Places inside vehicles haven't been marked as
128 // inside yet so this is incorrectly penalising for
129 // weather in vehicles.
130 value *= sight_penalty;
131 }
132 for( const auto &fld : cur_submap->get_field( sp ) ) {
133 const field_entry &cur = fld.second;
134 if( cur.is_transparent() ) {
135 continue;
136 }
137 // Fields are either transparent or not, however we want some to be translucent
138 value = value * cur.translucency();
139 }
140 // TODO: [lightmap] Have glass reduce light as well
141 return value;
142 };
143
144 if( cur_submap->is_uniform ) {
145 float value = calc_transp( sm_offset );
146 // if rebuild_all==true all values were already set to LIGHT_TRANSPARENCY_OPEN_AIR
147 if( !rebuild_all || value != LIGHT_TRANSPARENCY_OPEN_AIR ) {
148 for( int sx = 0; sx < SEEX; ++sx ) {
149 // init all sy indices in one go
150 std::uninitialized_fill_n( &transparency_cache[sm_offset.x + sx][sm_offset.y], SEEY, value );
151 }
152 }
153 } else {
154 for( int sx = 0; sx < SEEX; ++sx ) {
155 const int x = sx + sm_offset.x;
156 for( int sy = 0; sy < SEEY; ++sy ) {
157 const int y = sy + sm_offset.y;
158 transparency_cache[x][y] = calc_transp( { x, y } );
159 }
160 }
161 }
162 }
163 }
164 map_cache.transparency_cache_dirty.reset();
165 return true;
166}
An active or passive effect existing on a tile.
Definition: field.h:20
bool is_transparent() const
Definition: field.cpp:84
float translucency() const
Definition: field.cpp:79

References get_cache(), get_submap_at_grid(), get_weather(), field_entry::is_transparent(), LIGHT_TRANSPARENCY_OPEN_AIR, LIGHT_TRANSPARENCY_SOLID, MAPSIZE, MAPSIZE_X, MAPSIZE_Y, my_MAPSIZE, SEEX, SEEY, weather_type::sight_penalty, sm_to_ms_copy(), sx, sy, field_entry::translucency(), and weather_manager::weather_id.

Referenced by build_map_cache().

◆ build_vision_transparency_cache()

bool map::build_vision_transparency_cache ( const Character player)
protected

Definition at line 168 of file lightmap.cpp.

169{
170 const tripoint &p = player.pos();
171
172 bool dirty = false;
173
175
176 const auto check_vehicle_coverage = []( const vehicle * veh, point p ) -> bool {
177 return veh->obstacle_at_position( p ) == -1 && ( veh->part_with_feature( p, "AISLE", true ) != -1 || veh->part_with_feature( p, "PROTRUSION", true ) != -1 );
178 };
179
180 const optional_vpart_position player_vp = veh_at( p );
181
182 point player_mount;
183 if( player_vp ) {
184 player_mount = player_vp->vehicle().tripoint_to_mount( p );
185 }
186
187 int i = 0;
188 for( point adjacent : eight_adjacent_offsets ) {
190
191 // If we're crouching behind an obstacle, we can't see past it.
192 if( coverage( adjacent + p ) >= 30 ) {
193 dirty = true;
195 } else {
197 adjacent ) != four_diagonal_offsets.end() ) {
198 const optional_vpart_position adjacent_vp = veh_at( p + adjacent );
199
200 point adjacent_mount;
201 if( adjacent_vp ) {
202 adjacent_mount = adjacent_vp->vehicle().tripoint_to_mount( p );
203 }
204
205 if( ( player_vp &&
206 !player_vp->vehicle().check_rotated_intervening( player_mount,
207 player_vp->vehicle().tripoint_to_mount( p + adjacent ),
208 check_vehicle_coverage ) )
209 || ( adjacent_vp && ( !player_vp || &( player_vp->vehicle() ) != &( adjacent_vp->vehicle() ) ) &&
210 !adjacent_vp->vehicle().check_rotated_intervening( adjacent_vp->vehicle().tripoint_to_mount(
211 p ), adjacent_vp->vehicle().tripoint_to_mount( p + adjacent ),
212 check_vehicle_coverage ) ) ) {
213 dirty = true;
215 }
216 }
217 }
218
219 i++;
220 }
221 } else {
222 std::fill_n( &vision_transparency_cache[0], 8, VISION_ADJUST_NONE );
223 }
224 return dirty;
225}
@ CMM_CROUCH
Definition: character.h:103
bool movement_mode_is(character_movemode mode) const
Check against the character's current movement mode.
Definition: character.cpp:1540
int coverage(const tripoint &p) const
Returns coverage value of the tile.
Definition: map.cpp:6317
int part_with_feature(int p, const std::string &f, bool unbroken) const
Definition: vehicle.cpp:2521
int obstacle_at_position(point pos) const
Definition: vehicle.cpp:2583
@ VISION_ADJUST_NONE
Definition: lightmap.h:77

References CMM_CROUCH, coverage(), eight_adjacent_offsets, detail::find(), four_diagonal_offsets, Character::movement_mode_is(), vehicle::obstacle_at_position(), vehicle::part_with_feature(), Character::pos(), veh_at(), VISION_ADJUST_HIDDEN, VISION_ADJUST_NONE, VISION_ADJUST_SOLID, and vision_transparency_cache.

Referenced by build_map_cache().

◆ burn_body_part()

int map::burn_body_part ( player u,
field_entry cur,
body_part  bp,
int  scale 
)
private

Definition at line 124 of file map_field.cpp.

125{
126 int total_damage = 0;
127 const int intensity = cur.get_field_intensity();
128 const int damage = rng( 1, ( scale + intensity ) / 2 );
129 // A bit ugly, but better than being annoyed by acid when in hazmat
130 if( u.get_armor_type( DT_ACID, convert_bp( bp ) ) < damage ) {
131 const dealt_damage_instance ddi = u.deal_damage( nullptr, convert_bp( bp ).id(),
132 damage_instance( DT_ACID, damage ) );
133 total_damage += ddi.total_damage();
134 }
135 // Represents acid seeping in rather than being splashed on
137 1 + intensity ) ), bp, 0 );
138 return total_damage;
139}
units::quantity< V, B > rng(const units::quantity< V, B > &min, const units::quantity< V, B > &max)
Definition: artifact.cpp:32
const bodypart_str_id & convert_bp(body_part bp)
Returns the new id for old token.
Definition: bodypart.cpp:185
dealt_damage_instance deal_damage(Creature *source, bodypart_id bp, const damage_instance &d) override
Calls Creature::deal_damage and handles damaged effects (waking up, etc.)
Definition: character.cpp:8419
int get_armor_type(damage_type dt, bodypart_id bp) const override
Returns overall resistance to given type on the bod part.
Definition: character.cpp:6841
bool add_env_effect(const efftype_id &eff_id, body_part vector, int strength, const time_duration &dur, body_part bp=num_bp, int intensity=1, bool force=false)
Gives chance to save via environmental resist, returns false if resistance was successful.
Definition: creature.cpp:1118
int get_field_intensity() const
Definition: field.cpp:121
static constexpr time_duration from_turns(const T t)
Named constructors to get a duration representing a multiple of the named time units.
Definition: calendar.h:204
@ DT_ACID
Definition: damage.h:26
static const efftype_id effect_corroding("corroding")
int total_damage() const
Definition: damage.cpp:180

References Creature::add_env_effect(), convert_bp(), Character::deal_damage(), DT_ACID, effect_corroding, time_duration::from_turns(), Character::get_armor_type(), field_entry::get_field_intensity(), rng(), and dealt_damage_instance::total_damage().

Referenced by player_in_field().

◆ calc_max_populated_zlev()

int map::calc_max_populated_zlev ( )
private

Caclulate the greatest populated zlevel in the loaded submaps and save in the level cache.

fills the map::max_populated_zlev and returns it

Returns
max_populated_zlev value

Definition at line 9062 of file map.cpp.

9063{
9064 // cache is filled and valid, skip recalculation
9066 return max_populated_zlev->second;
9067 }
9068
9069 // We'll assume ground level is populated
9070 int max_z = 0;
9071
9072 for( int sz = 1; sz <= OVERMAP_HEIGHT; sz++ ) {
9073 bool level_done = false;
9074 for( int sx = 0; sx < my_MAPSIZE; sx++ ) {
9075 for( int sy = 0; sy < my_MAPSIZE; sy++ ) {
9076 const submap *sm = get_submap_at_grid( tripoint( sx, sy, sz ) );
9077 if( !sm->is_uniform ) {
9078 max_z = sz;
9079 level_done = true;
9080 break;
9081 }
9082 }
9083 if( level_done ) {
9084 break;
9085 }
9086 }
9087 }
9088
9089 max_populated_zlev = std::pair<tripoint, int>( get_abs_sub(), max_z );
9090 return max_z;
9091}
cata::optional< std::pair< tripoint, int > > max_populated_zlev
Definition: map.h:1986
tripoint get_abs_sub() const
return abs_sub
Definition: map.cpp:8350

References get_abs_sub(), get_submap_at_grid(), max_populated_zlev, my_MAPSIZE, OVERMAP_HEIGHT, coords::sm, sx, and sy.

Referenced by build_sunlight_cache().

◆ can_move_furniture()

bool map::can_move_furniture ( const tripoint pos,
player p = nullptr 
)
Strength determines what furniture the player can move

Definition at line 1503 of file map.cpp.

1504{
1505 if( !p ) {
1506 return false;
1507 }
1508 const furn_t &furniture_type = furn( pos ).obj();
1509 int required_str = furniture_type.move_str_req;
1510
1511 // Object can not be moved (or nothing there)
1512 if( required_str < 0 ) {
1513 return false;
1514 }
1515
1516 ///\EFFECT_STR determines what furniture the player can move
1517 int adjusted_str = p->str_cur;
1518 if( p->is_mounted() ) {
1519 auto mons = p->mounted_creature.get();
1520 if( mons->has_flag( MF_RIDEABLE_MECH ) && mons->mech_str_addition() != 0 ) {
1521 adjusted_str = mons->mech_str_addition();
1522 }
1523 }
1524 return adjusted_str >= required_str;
1525}
int str_cur
Definition: character.h:256
bool is_mounted() const
Definition: character.cpp:1064
shared_ptr_fast< monster > mounted_creature
Definition: character.h:1581
@ MF_RIDEABLE_MECH
Definition: mtype.h:115
int move_str_req
Definition: mapdata.h:515

References furn(), Character::is_mounted(), MF_RIDEABLE_MECH, Character::mounted_creature, furn_t::move_str_req, int_id< T >::obj(), wrapped_vehicle::pos, and Character::str_cur.

Referenced by grab().

◆ can_put_items() [1/2]

bool map::can_put_items ( const tripoint p) const

Definition at line 2356 of file map.cpp.

2357{
2358 if( can_put_items_ter_furn( p ) ) {
2359 return true;
2360 }
2361 const optional_vpart_position vp = veh_at( p );
2362 return static_cast<bool>( vp.part_with_feature( "CARGO", true ) );
2363}
bool can_put_items_ter_furn(const tripoint &p) const
Definition: map.cpp:2365

References can_put_items_ter_furn(), optional_vpart_position::part_with_feature(), and veh_at().

Referenced by can_put_items(), complete_construction(), haul(), and game::place_player().

◆ can_put_items() [2/2]

bool map::can_put_items ( point  p) const
inline

Definition at line 908 of file map.h.

908 {
909 return can_put_items( tripoint( p, abs_sub.z ) );
910 }
bool can_put_items(const tripoint &p) const
Definition: map.cpp:2356

References abs_sub, can_put_items(), and tripoint::z.

◆ can_put_items_ter_furn() [1/2]

bool map::can_put_items_ter_furn ( const tripoint p) const

◆ can_put_items_ter_furn() [2/2]

bool map::can_put_items_ter_furn ( point  p) const
inline

Definition at line 913 of file map.h.

913 {
915 }

References abs_sub, can_put_items_ter_furn(), and tripoint::z.

◆ can_see_trap_at()

bool map::can_see_trap_at ( const tripoint p,
const Character c 
) const

See trap::can_see, which is called for the trap here.

Definition at line 5193 of file map.cpp.

5194{
5195 return tr_at( p ).can_see( p, c );
5196}
const trap & tr_at(const tripoint &p) const
Definition: map.cpp:5198
constexpr double c
Definition: magic.cpp:1032
bool can_see(const tripoint &pos, const Character &p) const
Can player/npc p see this kind of trap, either by their memory (they known there is the trap) or by t...
Definition: trap.cpp:223

References c, trap::can_see(), and tr_at().

Referenced by can_examine_at(), and vehicle::autodrive_controller::check_drivable().

◆ check_and_set_seen_cache()

bool map::check_and_set_seen_cache ( const tripoint p) const

Definition at line 8876 of file map.cpp.

8877{
8878 std::bitset<MAPSIZE_X *MAPSIZE_Y> &memory_seen_cache =
8880 if( !memory_seen_cache[ static_cast<size_t>( p.x + p.y * MAPSIZE_Y ) ] ) {
8881 memory_seen_cache.set( static_cast<size_t>( p.x + p.y * MAPSIZE_Y ) );
8882 return true;
8883 }
8884 return false;
8885}
std::bitset< MAPSIZE_X *MAPSIZE_Y > map_memory_seen_cache
Definition: map.h:351

References get_cache(), level_cache::map_memory_seen_cache, MAPSIZE_Y, tripoint::x, tripoint::y, and tripoint::z.

Referenced by draw_maptile().

◆ check_seen_cache()

bool map::check_seen_cache ( const tripoint p) const

Definition at line 8869 of file map.cpp.

8870{
8871 std::bitset<MAPSIZE_X *MAPSIZE_Y> &memory_seen_cache =
8873 return !memory_seen_cache[ static_cast<size_t>( p.x + p.y * MAPSIZE_Y ) ];
8874}

References get_cache(), level_cache::map_memory_seen_cache, MAPSIZE_Y, tripoint::x, tripoint::y, and tripoint::z.

◆ check_submap_active_item_consistency()

std::vector< tripoint > map::check_submap_active_item_consistency ( )

Definition at line 4613 of file map.cpp.

4614{
4615 std::vector<tripoint> result;
4616 for( int z = -OVERMAP_DEPTH; z < OVERMAP_HEIGHT; ++z ) {
4617 for( int x = 0; x < MAPSIZE; ++x ) {
4618 for( int y = 0; y < MAPSIZE; ++y ) {
4619 tripoint p( x, y, z );
4620 submap *s = get_submap_at_grid( p );
4621 bool has_active_items = !s->active_items.get().empty();
4622 bool map_has_active_items = submaps_with_active_items.count( p + abs_sub.xy() );
4623 if( has_active_items != map_has_active_items ) {
4624 result.push_back( p + abs_sub.xy() );
4625 }
4626 }
4627 }
4628 }
4629 for( const tripoint &p : submaps_with_active_items ) {
4630 tripoint rel = p - abs_sub.xy();
4632 if( !map.contains( rel.xy() ) ) {
4633 result.push_back( p );
4634 }
4635 }
4636 return result;
4637}
std::vector< item_reference > get()
Returns a vector of all cached active item references.
Manage and cache data about a part of the map.
Definition: map.h:384

References abs_sub, submap::active_items, active_item_cache::get(), get_submap_at_grid(), map(), MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, point_zero, submaps_with_active_items, and tripoint::xy().

◆ check_vehicle_zones()

bool map::check_vehicle_zones ( int  zlev)

Definition at line 987 of file map.cpp.

988{
989 for( auto veh : get_cache( zlev ).zone_vehicles ) {
990 if( veh->zones_dirty ) {
991 return true;
992 }
993 }
994 return false;
995}

References get_cache().

Referenced by activity_on_turn_move_loot(), talk_function::basecamp_mission(), basecamp::distribute_food(), find_auto_consume(), basecamp::place_results(), and basecamp::validate_sort_points().

◆ clear_path()

bool map::clear_path ( const tripoint f,
const tripoint t,
int  range,
int  cost_min,
int  cost_max 
) const

Check whether there's a direct line of sight between F and T with the additional movecost restraints.

Checks two things:

  1. The sees() algorithm between F and T
  2. That moving over the line of sight would have a move_cost between cost_min and cost_max.

Definition at line 6468 of file map.cpp.

6470{
6471 // Ugly `if` for now
6472 if( !fov_3d && f.z != t.z ) {
6473 return false;
6474 }
6475
6476 if( f.z == t.z ) {
6477 if( ( range >= 0 && range < rl_dist( f.xy(), t.xy() ) ) ||
6478 !inbounds( t ) ) {
6479 return false; // Out of range!
6480 }
6481 bool is_clear = true;
6482 point last_point = f.xy();
6483 bresenham( f.xy(), t.xy(), 0,
6484 [this, &is_clear, cost_min, cost_max, &t, &last_point]( point new_point ) {
6485 // Exit before checking the last square, it's still reachable even if it is an obstacle.
6486 if( new_point.x == t.x && new_point.y == t.y ) {
6487 return false;
6488 }
6489
6490 const int cost = this->move_cost( new_point );
6491 if( cost < cost_min || cost > cost_max ||
6492 obstructed_by_vehicle_rotation( tripoint( last_point, t.z ), tripoint( new_point,
6493 t.z ) ) ) {
6494 is_clear = false;
6495 return false;
6496 }
6497
6498 last_point = new_point;
6499 return true;
6500 } );
6501 return is_clear;
6502 }
6503
6504 if( ( range >= 0 && range < rl_dist( f, t ) ) ||
6505 !inbounds( t ) ) {
6506 return false; // Out of range!
6507 }
6508 bool is_clear = true;
6509 tripoint last_point = f;
6510 bresenham( f, t, 0, 0,
6511 [this, &is_clear, cost_min, cost_max, t, &last_point]( const tripoint & new_point ) {
6512 // Exit before checking the last square, it's still reachable even if it is an obstacle.
6513 if( new_point == t ) {
6514 return false;
6515 }
6516
6517 // We have to check a weird case where the move is both vertical and horizontal
6518 if( new_point.z == last_point.z ) {
6519 const int cost = move_cost( new_point );
6520 if( cost < cost_min || cost > cost_max ||
6521 obstructed_by_vehicle_rotation( last_point, new_point ) ) {
6522 is_clear = false;
6523 return false;
6524 }
6525 } else {
6526 bool this_clear = false;
6527 const int max_z = std::max( new_point.z, last_point.z );
6528 if( !has_floor_or_support( {new_point.xy(), max_z} ) ) {
6529 const int cost = move_cost( {new_point.xy(), last_point.z} );
6530 if( cost > cost_min && cost < cost_max &&
6531 !obstructed_by_vehicle_rotation( last_point, new_point ) ) {
6532 this_clear = true;
6533 }
6534 }
6535
6536 if( !this_clear && has_floor_or_support( {last_point.xy(), max_z} ) ) {
6537 const int cost = move_cost( {last_point.xy(), new_point.z} );
6538 if( cost > cost_min && cost < cost_max &&
6539 !obstructed_by_vehicle_rotation( last_point, new_point ) ) {
6540 this_clear = true;
6541 }
6542 }
6543
6544 if( !this_clear ) {
6545 is_clear = false;
6546 return false;
6547 }
6548 }
6549
6550 last_point = new_point;
6551 return true;
6552 } );
6553 return is_clear;
6554}
bool has_floor_or_support(const tripoint &p) const
Definition: map.cpp:2097
int move_cost(const tripoint &p, const vehicle *ignored_vehicle=nullptr) const
Calculate the cost to move past the tile at p.
Definition: map.cpp:1838
void bresenham(point p1, point p2, int t, const std::function< bool(point)> &interact)
The actual Bresenham algorithm in 2D and 3D, everything else should call these and pass in an interac...
Definition: line.cpp:24

References bresenham(), fov_3d, inbounds(), obstructed_by_vehicle_rotation(), rl_dist(), tripoint::xy(), and tripoint::z.

Referenced by find_best_fire(), player::get_eligible_containers_for_crafting(), has_clear_path_to_pickup_items(), points_for_gas_cloud(), process_fields_in_submap(), mattack::riotbot(), game::start_game(), and vehicle_selector::vehicle_selector().

◆ clear_spawns()

void map::clear_spawns ( )

Definition at line 7797 of file map.cpp.

7798{
7799 for( auto &smap : grid ) {
7800 smap->spawns.clear();
7801 }
7802}

References grid.

Referenced by defense_game::init_map().

◆ clear_traps()

void map::clear_traps ( )

Definition at line 7804 of file map.cpp.

7805{
7806 for( auto &smap : grid ) {
7807 for( int x = 0; x < SEEX; x++ ) {
7808 for( int y = 0; y < SEEY; y++ ) {
7809 const point p( x, y );
7810 smap->set_trap( p, tr_null );
7811 }
7812 }
7813 }
7814
7815 // Forget about all trap locations.
7816 for( auto &i : traplocs ) {
7817 i.clear();
7818 }
7819}

References grid, SEEX, SEEY, tr_null, and traplocs.

Referenced by defense_game::init_map().

◆ clear_vehicle_cache()

void map::clear_vehicle_cache ( )

Definition at line 371 of file map.cpp.

372{
373 const int zmin = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
374 const int zmax = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
375 for( int zlev = zmin; zlev <= zmax; zlev++ ) {
376 level_cache &ch = get_cache( zlev );
377 while( !ch.veh_cached_parts.empty() ) {
378 const auto part = ch.veh_cached_parts.begin();
379 const auto &p = part->first;
380 if( inbounds( p ) ) {
381 ch.veh_exists_at[p.x][p.y] = false;
382 }
383 ch.veh_cached_parts.erase( part );
384 }
385 ch.veh_in_active_range = false;
386 }
387}

References abs_sub, get_cache(), inbounds(), OVERMAP_DEPTH, OVERMAP_HEIGHT, level_cache::veh_cached_parts, level_cache::veh_exists_at, level_cache::veh_in_active_range, tripoint::z, and zlevels.

Referenced by editmap::mapgen_preview(), game::place_player_overmap(), reset_vehicle_cache(), rotate(), shift(), and game::vertical_shift().

◆ clear_vehicle_list()

void map::clear_vehicle_list ( int  zlev)

Definition at line 389 of file map.cpp.

390{
391 auto &ch = get_cache( zlev );
392 ch.vehicle_list.clear();
393 ch.zone_vehicles.clear();
394
396}

References get_cache(), and last_full_vehicle_list_dirty.

Referenced by editmap::mapgen_preview(), editmap::mapgen_veh_destroy(), game::place_player_overmap(), rotate(), and shift().

◆ clear_vehicle_point_from_cache()

void map::clear_vehicle_point_from_cache ( vehicle veh,
const tripoint pt 
)

Definition at line 353 of file map.cpp.

354{
355 if( veh == nullptr ) {
356 debugmsg( "Tried to clear null vehicle from cache" );
357 return;
358 }
359
360 level_cache &ch = get_cache( pt.z );
361 if( inbounds( pt ) ) {
362 ch.veh_exists_at[pt.x][pt.y] = false;
363 }
364 auto it = ch.veh_cached_parts.find( pt );
365 if( it != ch.veh_cached_parts.end() && it->second.first == veh ) {
366 ch.veh_cached_parts.erase( it );
367 }
368
369}

References debugmsg, get_cache(), inbounds(), level_cache::veh_cached_parts, level_cache::veh_exists_at, tripoint::x, tripoint::y, and tripoint::z.

Referenced by vehicle::advance_precalc_mounts(), veh_interact::complete_vehicle(), and vehicle::part_removal_cleanup().

◆ climb_difficulty()

int map::climb_difficulty ( const tripoint p) const

Checks 3x3 block centered on p for terrain to climb.

Returns
Difficulty of climbing check from point p.

Definition at line 2027 of file map.cpp.

2028{
2029 if( p.z > OVERMAP_HEIGHT || p.z < -OVERMAP_DEPTH ) {
2030 debugmsg( "climb_difficulty on out of bounds point: %d, %d, %d", p.x, p.y, p.z );
2031 return INT_MAX;
2032 }
2033
2034 int best_difficulty = INT_MAX;
2035 int blocks_movement = 0;
2036 if( has_flag( "LADDER", p ) ) {
2037 // Really easy, but you have to stand on the tile
2038 return 1;
2039 } else if( has_flag( TFLAG_RAMP, p ) || has_flag( TFLAG_RAMP_UP, p ) ||
2040 has_flag( TFLAG_RAMP_DOWN, p ) ) {
2041 // We're on something stair-like, so halfway there already
2042 best_difficulty = 7;
2043 }
2044
2045 for( const auto &pt : points_in_radius( p, 1 ) ) {
2046 if( impassable_ter_furn( pt ) ) {
2047 // TODO: Non-hardcoded climbability
2048 best_difficulty = std::min( best_difficulty, 10 );
2049 blocks_movement++;
2050 } else if( veh_at( pt ) ) {
2051 // Vehicle tiles are quite good for climbing
2052 // TODO: Penalize spiked parts?
2053 best_difficulty = std::min( best_difficulty, 7 );
2054 }
2055
2056 if( best_difficulty > 5 && has_flag( "CLIMBABLE", pt ) ) {
2057 best_difficulty = 5;
2058 }
2059 }
2060
2061 // TODO: Make this more sensible - check opposite sides, not just movement blocker count
2062 return best_difficulty - blocks_movement;
2063}
bool impassable_ter_furn(const tripoint &p) const
Definition: map.cpp:1886
@ TFLAG_RAMP_UP
Definition: mapdata.h:313
@ TFLAG_RAMP
Definition: mapdata.h:314
@ TFLAG_RAMP_DOWN
Definition: mapdata.h:312

References debugmsg, has_flag(), impassable_ter_furn(), OVERMAP_DEPTH, OVERMAP_HEIGHT, points_in_radius(), TFLAG_RAMP, TFLAG_RAMP_DOWN, TFLAG_RAMP_UP, veh_at(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by map_funcs::climbing_cost().

◆ clip_to_bounds() [1/3]

void map::clip_to_bounds ( int &  x,
int &  y 
) const

Definition at line 9005 of file map.cpp.

9006{
9007 if( x < 0 ) {
9008 x = 0;
9009 } else if( x >= SEEX * my_MAPSIZE ) {
9010 x = SEEX * my_MAPSIZE - 1;
9011 }
9012
9013 if( y < 0 ) {
9014 y = 0;
9015 } else if( y >= SEEY * my_MAPSIZE ) {
9016 y = SEEY * my_MAPSIZE - 1;
9017 }
9018}

References my_MAPSIZE, SEEX, and SEEY.

◆ clip_to_bounds() [2/3]

void map::clip_to_bounds ( int &  x,
int &  y,
int &  z 
) const

Definition at line 9020 of file map.cpp.

9021{
9022 clip_to_bounds( x, y );
9023 if( z < -OVERMAP_DEPTH ) {
9024 z = -OVERMAP_DEPTH;
9025 } else if( z > OVERMAP_HEIGHT ) {
9026 z = OVERMAP_HEIGHT;
9027 }
9028}
void clip_to_bounds(tripoint &p) const
Clips the coordinates of p to fit the map bounds.
Definition: map.cpp:9000

References clip_to_bounds(), OVERMAP_DEPTH, and OVERMAP_HEIGHT.

◆ clip_to_bounds() [3/3]

void map::clip_to_bounds ( tripoint p) const

Clips the coordinates of p to fit the map bounds.

Definition at line 9000 of file map.cpp.

9001{
9002 clip_to_bounds( p.x, p.y, p.z );
9003}

References clip_to_bounds(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by MapgenRemovePartHandler::add_item_or_charges(), clip_to_bounds(), and route().

◆ close_door()

bool map::close_door ( const tripoint p,
bool  inside,
bool  check_only 
)

Definition at line 4033 of file map.cpp.

4034{
4035 if( has_flag( "OPENCLOSE_INSIDE", p ) && !inside ) {
4036 return false;
4037 }
4038
4039 const auto &ter = this->ter( p ).obj();
4040 const auto &furn = this->furn( p ).obj();
4041 if( ter.close && !furn.id ) {
4042 if( !check_only ) {
4043 sounds::sound( p, 10, sounds::sound_t::movement, _( "swish" ), true,
4044 "close_door", ter.id.str() );
4045 ter_set( p, ter.close );
4046 }
4047 return true;
4048 } else if( furn.close ) {
4049 if( !check_only ) {
4050 sounds::sound( p, 10, sounds::sound_t::movement, _( "swish" ), true,
4051 "close_door", furn.id.str() );
4052 furn_set( p, furn.close );
4053 }
4054 return true;
4055 }
4056 return false;
4057}
const string_id< T > & id() const
Definition: ammo_effect.cpp:33

References _, furn(), furn_set(), has_flag(), int_id< T >::id(), sounds::movement, int_id< T >::obj(), sounds::sound(), string_id< T >::str(), ter(), and ter_set().

Referenced by can_interact_at(), doors::close_door(), and game::try_get_right_click_action().

◆ collapse_at()

void map::collapse_at ( const tripoint p,
bool  silent,
bool  was_supporting = false,
bool  destroy_pos = true 
)

Causes a collapse at p, such as from destroying a wall.

Definition at line 2967 of file map.cpp.

2969{
2970 const bool supports = was_supporting || has_flag( TFLAG_SUPPORTS_ROOF, p );
2971 const bool wall = was_supporting || has_flag( TFLAG_WALL, p );
2972 // don't bash again if the caller already bashed here
2973 if( destroy_pos ) {
2974 destroy( p, silent );
2975 crush( p );
2976 make_rubble( p );
2977 }
2978 const bool still_supports = has_flag( TFLAG_SUPPORTS_ROOF, p );
2979
2980 // If something supporting the roof collapsed, see what else collapses
2981 if( supports && !still_supports ) {
2982 for( const tripoint &t : points_in_radius( p, 1 ) ) {
2983 // If z-levels are off, tz == t, so we end up skipping a lot of stuff to avoid bugs.
2984 const tripoint &tz = tripoint( t.xy(), t.z + 1 );
2985 // if nothing above us had the chance of collapsing, move on
2986 if( !one_in( collapse_check( tz ) ) ) {
2987 continue;
2988 }
2989 // if a wall collapses, walls without support from below risk collapsing and
2990 //propagate the collapse upwards
2991 if( zlevels && wall && p == t && has_flag( TFLAG_WALL, tz ) ) {
2992 collapse_at( tz, silent );
2993 }
2994 // floors without support from below risk collapsing into open air and can propagate
2995 // the collapse horizontally but not vertically
2996 if( p != t && ( has_flag( TFLAG_SUPPORTS_ROOF, t ) && has_flag( TFLAG_COLLAPSES, t ) ) ) {
2997 collapse_at( t, silent );
2998 }
2999 // this tile used to support a roof, now it doesn't, which means there is only
3000 // open air above us
3001 if( zlevels ) {
3002 ter_set( tz, t_open_air );
3003 furn_set( tz, f_null );
3005 }
3006 }
3007 }
3008 // it would be great to check if collapsing ceilings smashed through the floor, but
3009 // that's not handled for now
3010}
void crush(const tripoint &p)
Definition: map.cpp:3730
int collapse_check(const tripoint &p)
Checks if a square should collapse, returns the X for the one_in(X) collapse chance.
Definition: map.cpp:2918
void make_rubble(const tripoint &p, const furn_id &rubble_type, bool items, const ter_id &floor_type, bool overwrite=false)
Generates rubble at the given location, if overwrite is true it just writes on top of what currently ...
Definition: map.cpp:2567
@ TFLAG_COLLAPSES
Definition: mapdata.h:288
@ TFLAG_WALL
Definition: mapdata.h:300

References collapse_at(), collapse_check(), crush(), destroy(), f_null, furn_set(), has_flag(), make_rubble(), one_in(), points_in_radius(), propagate_suspension_check(), silent, t_open_air, ter_set(), TFLAG_COLLAPSES, TFLAG_SUPPORTS_ROOF, TFLAG_WALL, and zlevels.

Referenced by bash_ter_success(), collapse_at(), and talk_function::loot_building().

◆ collapse_check()

int map::collapse_check ( const tripoint p)

Checks if a square should collapse, returns the X for the one_in(X) collapse chance.

Definition at line 2918 of file map.cpp.

2919{
2920 const bool collapses = has_flag( TFLAG_COLLAPSES, p );
2921 const bool supports_roof = has_flag( TFLAG_SUPPORTS_ROOF, p );
2922
2923 int num_supports = p.z == -OVERMAP_DEPTH ? 0 : -5;
2924 // if there's support below, things are less likely to collapse
2925 if( p.z > -OVERMAP_DEPTH ) {
2926 const tripoint &pbelow = tripoint( p.xy(), p.z - 1 );
2927 for( const tripoint &tbelow : points_in_radius( pbelow, 1 ) ) {
2928 if( has_flag( TFLAG_SUPPORTS_ROOF, pbelow ) ) {
2929 num_supports += 1;
2930 if( has_flag( TFLAG_WALL, pbelow ) ) {
2931 num_supports += 2;
2932 }
2933 if( tbelow == pbelow ) {
2934 num_supports += 2;
2935 }
2936 }
2937 }
2938 }
2939
2940 for( const tripoint &t : points_in_radius( p, 1 ) ) {
2941 if( p == t ) {
2942 continue;
2943 }
2944
2945 if( collapses ) {
2946 if( has_flag( TFLAG_COLLAPSES, t ) ) {
2947 num_supports++;
2948 } else if( has_flag( TFLAG_SUPPORTS_ROOF, t ) ) {
2949 num_supports += 2;
2950 }
2951 } else if( supports_roof ) {
2952 if( has_flag( TFLAG_SUPPORTS_ROOF, t ) ) {
2953 if( has_flag( TFLAG_WALL, t ) ) {
2954 num_supports += 4;
2955 } else if( !has_flag( TFLAG_COLLAPSES, t ) ) {
2956 num_supports += 3;
2957 }
2958 }
2959 }
2960 }
2961
2962 return 1.7 * num_supports;
2963}

References has_flag(), OVERMAP_DEPTH, points_in_radius(), TFLAG_COLLAPSES, TFLAG_SUPPORTS_ROOF, TFLAG_WALL, tripoint::xy(), and tripoint::z.

Referenced by collapse_at().

◆ collapse_invalid_suspension()

void map::collapse_invalid_suspension ( const tripoint point)

Triggers a recursive collapse of suspended tiles based on their support validity.

Definition at line 3021 of file map.cpp.

3022{
3023 if( !is_suspension_valid( point ) ) {
3025 furn_set( point, f_null );
3026
3028 }
3029}
bool is_suspension_valid(const tripoint &point)
Checks the four orientations in which a suspended tile could be valid, and returns if the tile is val...
Definition: map.cpp:3031

References f_null, furn_set(), is_suspension_valid(), propagate_suspension_check(), t_open_air, and ter_set().

Referenced by drop_everything(), and propagate_suspension_check().

◆ combined_movecost()

int map::combined_movecost ( const tripoint from,
const tripoint to,
const vehicle ignored_vehicle = nullptr,
int  modifier = 0,
bool  flying = false,
bool  via_ramp = false 
) const

Cost to move out of one tile and into the next.

Returns
The cost in turns to move out of tripoint from and into to

Definition at line 1896 of file map.cpp.

1899{
1900 const int mults[4] = { 0, 50, 71, 100 };
1901 const int cost1 = move_cost( from, ignored_vehicle );
1902 const int cost2 = move_cost( to, ignored_vehicle );
1903 // Multiply cost depending on the number of differing axes
1904 // 0 if all axes are equal, 100% if only 1 differs, 141% for 2, 200% for 3
1905 size_t match = trigdist ? ( from.x != to.x ) + ( from.y != to.y ) + ( from.z != to.z ) : 1;
1906 if( flying || from.z == to.z ) {
1907 return ( cost1 + cost2 + modifier ) * mults[match] / 2;
1908 }
1909
1910 // Inter-z-level movement by foot (not flying)
1911 if( !valid_move( from, to, false, via_ramp ) ) {
1912 return 0;
1913 }
1914
1915 // TODO: Penalize for using stairs
1916 return ( cost1 + cost2 + modifier ) * mults[match] / 2;
1917}
bool valid_move(const tripoint &from, const tripoint &to, bool bash=false, bool flying=false, bool via_ramp=false) const
Returns true if a creature could walk from from to to in one step.
Definition: map.cpp:1919

References move_cost(), trigdist, valid_move(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by npc::move_away_from(), npc::move_to(), and game::walk_move().

◆ computer_at()

computer * map::computer_at ( const tripoint p)

Definition at line 5615 of file map.cpp.

5616{
5617 if( !inbounds( p ) ) {
5618 return nullptr;
5619 }
5620
5621 point l;
5622 submap *const sm = get_submap_at( p, l );
5623 return sm->get_computer( l );
5624}

References get_submap_at(), inbounds(), and coords::sm.

Referenced by mission_start::reveal_lab_train_depot(), and game::use_computer().

◆ copy_grid()

void map::copy_grid ( const tripoint to,
const tripoint from 
)
protected

Definition at line 7582 of file map.cpp.

7583{
7584 const auto smap = get_submap_at_grid( from );
7585 setsubmap( get_nonant( to ), smap );
7586 for( auto &it : smap->vehicles ) {
7587 it->sm_pos = to;
7588 }
7589}
void setsubmap(size_t grididx, submap *smap)
Set the submap pointer in grid at the give index.
Definition: map.cpp:8364
size_t get_nonant(const tripoint &gridp) const
Get the index of a submap pointer in the grid given by grid coordinates.
Definition: map.cpp:8397

References get_nonant(), get_submap_at_grid(), and setsubmap().

Referenced by shift().

◆ could_see_items() [1/2]

bool map::could_see_items ( const tripoint p,
const Creature who 
) const

Check if the creature could see items at p if there were any items.

This is similar to sees_some_items, but it does not check that there are actually any items.

Definition at line 4806 of file map.cpp.

4807{
4808 return could_see_items( p, who.pos() );
4809}
virtual const tripoint & pos() const =0
bool could_see_items(const tripoint &p, const Creature &who) const
Check if the creature could see items at p if there were any items.
Definition: map.cpp:4806

References could_see_items(), and Creature::pos().

Referenced by could_see_items(), game::print_items_info(), and sees_some_items().

◆ could_see_items() [2/2]

bool map::could_see_items ( const tripoint p,
const tripoint from 
) const

Definition at line 4811 of file map.cpp.

4812{
4813 static const std::string container_string( "CONTAINER" );
4814 const bool container = has_flag_ter_or_furn( container_string, p );
4815 const bool sealed = has_flag_ter_or_furn( TFLAG_SEALED, p );
4816 if( sealed && container ) {
4817 // never see inside of sealed containers
4818 return false;
4819 }
4820 if( container ) {
4821 // can see inside of containers if adjacent or
4822 // on top of the container
4823 return ( std::abs( p.x - from.x ) <= 1 &&
4824 std::abs( p.y - from.y ) <= 1 &&
4825 std::abs( p.z - from.z ) <= 1 );
4826 }
4827 return true;
4828}
bool has_flag_ter_or_furn(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2380
@ TFLAG_SEALED
Definition: mapdata.h:285

References has_flag_ter_or_furn(), TFLAG_SEALED, tripoint::x, tripoint::y, and tripoint::z.

◆ coverage()

int map::coverage ( const tripoint p) const

Returns coverage value of the tile.

Definition at line 6317 of file map.cpp.

6318{
6319 if( const auto obstacle_f = furn( p ) ) {
6320 return obstacle_f->coverage;
6321 }
6322 if( const auto vp = veh_at( p ) ) {
6323 if( vp->obstacle_at_part() ) {
6324 return 60;
6325 } else if( !vp->part_with_feature( VPFLAG_AISLE, true ) &&
6326 !vp->part_with_feature( "PROTRUSION", true ) ) {
6327 return 45;
6328 }
6329 }
6330 return ter( p )->coverage;
6331}
@ VPFLAG_AISLE
Definition: veh_type.h:40

References map_data_common_t::coverage, furn(), ter(), veh_at(), and VPFLAG_AISLE.

Referenced by build_vision_transparency_cache(), and game::print_terrain_info().

◆ create_anomaly() [1/2]

void map::create_anomaly ( const tripoint p,
artifact_natural_property  prop,
bool  create_rubble = true 
)

Definition at line 6357 of file mapgen.cpp.

6358{
6359 // TODO: Z
6360 point c( cp.xy() );
6361 if( create_rubble ) {
6362 rough_circle( this, t_dirt, c, 11 );
6363 rough_circle_furn( this, f_rubble, c, 5 );
6364 furn_set( c, f_null );
6365 }
6366 switch( prop ) {
6367 case ARTPROP_WRIGGLING:
6368 case ARTPROP_MOVING:
6369 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6370 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6371 if( furn( point( i, j ) ) == f_rubble ) {
6372 add_field( {i, j, abs_sub.z}, fd_push_items, 1 );
6373 if( one_in( 3 ) ) {
6374 spawn_item( point( i, j ), "rock" );
6375 }
6376 }
6377 }
6378 }
6379 break;
6380
6381 case ARTPROP_GLOWING:
6382 case ARTPROP_GLITTERING:
6383 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6384 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6385 if( furn( point( i, j ) ) == f_rubble && one_in( 2 ) ) {
6386 mtrap_set( this, point( i, j ), tr_glow );
6387 }
6388 }
6389 }
6390 break;
6391
6392 case ARTPROP_HUMMING:
6393 case ARTPROP_RATTLING:
6394 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6395 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6396 if( furn( point( i, j ) ) == f_rubble && one_in( 2 ) ) {
6397 mtrap_set( this, point( i, j ), tr_hum );
6398 }
6399 }
6400 }
6401 break;
6402
6403 case ARTPROP_WHISPERING:
6404 case ARTPROP_ENGRAVED:
6405 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6406 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6407 if( furn( point( i, j ) ) == f_rubble && one_in( 3 ) ) {
6408 mtrap_set( this, point( i, j ), tr_shadow );
6409 }
6410 }
6411 }
6412 break;
6413
6414 case ARTPROP_BREATHING:
6415 for( int i = c.x - 1; i <= c.x + 1; i++ ) {
6416 for( int j = c.y - 1; j <= c.y + 1; j++ ) {
6417 if( i == c.x && j == c.y ) {
6418 place_spawns( GROUP_BREATHER_HUB, 1, point( i, j ), point( i, j ), 1,
6419 true );
6420 } else {
6421 place_spawns( GROUP_BREATHER, 1, point( i, j ), point( i, j ), 1, true );
6422 }
6423 }
6424 }
6425 break;
6426
6427 case ARTPROP_DEAD:
6428 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6429 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6430 if( furn( point( i, j ) ) == f_rubble ) {
6431 mtrap_set( this, point( i, j ), tr_drain );
6432 }
6433 }
6434 }
6435 break;
6436
6437 case ARTPROP_ITCHY:
6438 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6439 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6440 if( furn( point( i, j ) ) == f_rubble ) {
6441 set_radiation( point( i, j ), rng( 0, 10 ) );
6442 }
6443 }
6444 }
6445 break;
6446
6447 case ARTPROP_ELECTRIC:
6448 case ARTPROP_CRACKLING:
6449 add_field( {c, abs_sub.z}, fd_shock_vent, 3 );
6450 break;
6451
6452 case ARTPROP_SLIMY:
6453 add_field( {c, abs_sub.z}, fd_acid_vent, 3 );
6454 break;
6455
6456 case ARTPROP_WARM:
6457 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6458 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6459 if( furn( point( i, j ) ) == f_rubble ) {
6460 add_field( {i, j, abs_sub.z}, fd_fire_vent, 1 + ( rl_dist( c, point( i, j ) ) % 3 ) );
6461 }
6462 }
6463 }
6464 break;
6465
6466 case ARTPROP_SCALED:
6467 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6468 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6469 if( furn( point( i, j ) ) == f_rubble ) {
6470 mtrap_set( this, point( i, j ), tr_snake );
6471 }
6472 }
6473 }
6474 break;
6475
6476 case ARTPROP_FRACTAL:
6477 create_anomaly( c + point( -4, -4 ),
6478 static_cast<artifact_natural_property>( rng( ARTPROP_NULL + 1, ARTPROP_MAX - 1 ) ) );
6479 create_anomaly( c + point( 4, -4 ),
6480 static_cast<artifact_natural_property>( rng( ARTPROP_NULL + 1, ARTPROP_MAX - 1 ) ) );
6481 create_anomaly( c + point( -4, 4 ),
6482 static_cast<artifact_natural_property>( rng( ARTPROP_NULL + 1, ARTPROP_MAX - 1 ) ) );
6483 create_anomaly( c + point( 4, -4 ),
6484 static_cast<artifact_natural_property>( rng( ARTPROP_NULL + 1, ARTPROP_MAX - 1 ) ) );
6485 break;
6486 default:
6487 break;
6488 }
6489}
bool add_field(const tripoint &p, const field_type_id &type_id, int intensity=INT_MAX, const time_duration &age=0_turns, bool hit_player=true)
Add field entry at point, or set intensity if present.
Definition: map.cpp:5469
void create_anomaly(const tripoint &p, artifact_natural_property prop, bool create_rubble=true)
Definition: mapgen.cpp:6357
void set_radiation(const tripoint &p, int value)
Definition: map.cpp:4105
void spawn_item(const tripoint &p, const itype_id &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
Definition: map.cpp:4253
void place_spawns(const mongroup_id &group, int chance, point p1, point p2, float density, bool individual=false, bool friendly=false, const std::string &name="NONE", int mission_id=-1)
Definition: mapgen.cpp:5427
artifact_natural_property
Definition: enums.h:152
@ ARTPROP_GLITTERING
Definition: enums.h:162
@ ARTPROP_ITCHY
Definition: enums.h:161
@ ARTPROP_RATTLING
Definition: enums.h:168
@ ARTPROP_WRIGGLING
Definition: enums.h:154
@ ARTPROP_HUMMING
Definition: enums.h:156
@ ARTPROP_WHISPERING
Definition: enums.h:158
@ ARTPROP_ENGRAVED
Definition: enums.h:165
@ ARTPROP_ELECTRIC
Definition: enums.h:163
@ ARTPROP_FRACTAL
Definition: enums.h:170
@ ARTPROP_SCALED
Definition: enums.h:169
@ ARTPROP_GLOWING
Definition: enums.h:155
@ ARTPROP_NULL
Definition: enums.h:153
@ ARTPROP_DEAD
Definition: enums.h:160
@ ARTPROP_BREATHING
Definition: enums.h:159
@ ARTPROP_MAX
Definition: enums.h:171
@ ARTPROP_CRACKLING
Definition: enums.h:166
@ ARTPROP_WARM
Definition: enums.h:167
@ ARTPROP_MOVING
Definition: enums.h:157
@ ARTPROP_SLIMY
Definition: enums.h:164
field_type_id fd_fire_vent
Definition: field_type.cpp:351
field_type_id fd_acid_vent
Definition: field_type.cpp:357
field_type_id fd_push_items
Definition: field_type.cpp:355
field_type_id fd_shock_vent
Definition: field_type.cpp:356
furn_id f_rubble
Definition: mapdata.cpp:1099
void rough_circle(map *m, const ter_id &type, point p, int rad)
Definition: mapgen.cpp:6524
static const mongroup_id GROUP_BREATHER("GROUP_BREATHER")
void rough_circle_furn(map *m, const furn_id &type, point p, int rad)
Definition: mapgen.cpp:6528
static const mongroup_id GROUP_BREATHER_HUB("GROUP_BREATHER_HUB")
void mtrap_set(map *m, point p, trap_id type)
static const trap_str_id tr_drain("tr_drain")
static const trap_str_id tr_snake("tr_snake")
static const trap_str_id tr_shadow("tr_shadow")
trap_id tr_glow
Definition: trap.cpp:312
trap_id tr_hum
Definition: trap.cpp:313

References abs_sub, add_field(), ARTPROP_BREATHING, ARTPROP_CRACKLING, ARTPROP_DEAD, ARTPROP_ELECTRIC, ARTPROP_ENGRAVED, ARTPROP_FRACTAL, ARTPROP_GLITTERING, ARTPROP_GLOWING, ARTPROP_HUMMING, ARTPROP_ITCHY, ARTPROP_MAX, ARTPROP_MOVING, ARTPROP_NULL, ARTPROP_RATTLING, ARTPROP_SCALED, ARTPROP_SLIMY, ARTPROP_WARM, ARTPROP_WHISPERING, ARTPROP_WRIGGLING, c, create_anomaly(), f_null, f_rubble, fd_acid_vent, fd_fire_vent, fd_push_items, fd_shock_vent, furn(), furn_set(), GROUP_BREATHER, GROUP_BREATHER_HUB, mtrap_set(), one_in(), place_spawns(), rl_dist(), rng(), rough_circle(), rough_circle_furn(), set_radiation(), spawn_item(), t_dirt, tr_drain, tr_glow, tr_hum, tr_shadow, tr_snake, tripoint::xy(), and tripoint::z.

Referenced by create_anomaly(), debug_menu::debug(), draw_lab(), and MapExtras::mx_portal_in().

◆ create_anomaly() [2/2]

void map::create_anomaly ( point  cp,
artifact_natural_property  prop,
bool  create_rubble = true 
)
inline

Definition at line 1330 of file map.h.

1330 {
1331 create_anomaly( tripoint( cp, abs_sub.z ), prop, create_rubble );
1332 }

References abs_sub, create_anomaly(), and tripoint::z.

◆ create_burnproducts()

void map::create_burnproducts ( const tripoint p,
const item fuel,
const units::mass burned_mass 
)

Definition at line 96 of file map_field.cpp.

97{
98 std::vector<material_id> all_mats = fuel.made_of();
99 if( all_mats.empty() ) {
100 return;
101 }
102 // Items that are multiple materials are assumed to be equal parts each.
103 const units::mass by_weight = burned_mass / all_mats.size();
104 for( material_id &mat : all_mats ) {
105 for( auto &bp : mat->burn_products() ) {
106 itype_id id = bp.first;
107 // Spawning the same item as the one that was just burned is pointless
108 // and leads to infinite recursion.
109 if( fuel.typeId() == id ) {
110 continue;
111 }
112 const float eff = bp.second;
113 const int n = std::floor( eff * ( by_weight / id->weight ) );
114
115 if( n <= 0 ) {
116 continue;
117 }
118 spawn_item( p, id, n, 1, calendar::turn );
119 }
120 }
121}
const std::string id
Definition: basecamp.h:87

References base_camps::id, item::made_of(), spawn_item(), calendar::turn, and item::typeId().

Referenced by MapExtras::burned_ground_parser(), and process_fields_in_submap().

◆ create_hot_air()

void map::create_hot_air ( const tripoint p,
int  intensity 
)
private

Definition at line 363 of file map_field.cpp.

364{
365 field_type_id hot_air;
366 switch( intensity ) {
367 case 1:
368 hot_air = fd_hot_air1;
369 break;
370 case 2:
371 hot_air = fd_hot_air2;
372 break;
373 case 3:
374 hot_air = fd_hot_air3;
375 break;
376 case 4:
377 hot_air = fd_hot_air4;
378 break;
379 default:
380 debugmsg( "Tried to spread hot air with intensity %d", intensity );
381 return;
382 }
383
384 for( int counter = 0; counter < 5; counter++ ) {
385 tripoint dst( p + point( rng( -1, 1 ), rng( -1, 1 ) ) );
386 add_field( dst, hot_air, 1 );
387 }
388}
field_type_id fd_hot_air3
Definition: field_type.cpp:381
field_type_id fd_hot_air2
Definition: field_type.cpp:380
field_type_id fd_hot_air1
Definition: field_type.cpp:379
field_type_id fd_hot_air4
Definition: field_type.cpp:382

References add_field(), debugmsg, fd_hot_air1, fd_hot_air2, fd_hot_air3, fd_hot_air4, and rng().

Referenced by process_fields_in_submap().

◆ creature_in_field()

void map::creature_in_field ( Creature critter)

Apply field effects to the creature when it's on a square with fields.

Definition at line 1563 of file map_field.cpp.

1564{
1565 bool in_vehicle = false;
1566 bool inside_vehicle = false;
1567 player *u = critter.as_player();
1568 if( critter.is_monster() ) {
1569 monster_in_field( *static_cast<monster *>( &critter ) );
1570 } else {
1571 if( u ) {
1572 in_vehicle = u->in_vehicle;
1573 // If we are in a vehicle figure out if we are inside (reduces effects usually)
1574 // and what part of the vehicle we need to deal with.
1575 if( in_vehicle ) {
1576 if( const optional_vpart_position vp = veh_at( u->pos() ) ) {
1577 if( vp->is_inside() ) {
1578 inside_vehicle = true;
1579 }
1580 }
1581 }
1582 player_in_field( *u );
1583 }
1584 }
1585
1586 field &curfield = get_field( critter.pos() );
1587 for( auto &field_entry_it : curfield ) {
1588 field_entry &cur_field_entry = field_entry_it.second;
1589 if( !cur_field_entry.is_field_alive() ) {
1590 continue;
1591 }
1592 const field_type_id cur_field_id = cur_field_entry.get_field_type();
1593
1594 for( const auto &fe : cur_field_entry.field_effects() ) {
1595 if( in_vehicle && fe.immune_in_vehicle ) {
1596 continue;
1597 }
1598 if( inside_vehicle && fe.immune_inside_vehicle ) {
1599 continue;
1600 }
1601 if( !inside_vehicle && fe.immune_outside_vehicle ) {
1602 continue;
1603 }
1604 if( in_vehicle && !one_in( fe.chance_in_vehicle ) ) {
1605 continue;
1606 }
1607 if( inside_vehicle && !one_in( fe.chance_inside_vehicle ) ) {
1608 continue;
1609 }
1610 if( !inside_vehicle && !one_in( fe.chance_outside_vehicle ) ) {
1611 continue;
1612 }
1613
1614 const effect field_fx = fe.get_effect();
1615 if( critter.is_immune_field( cur_field_id ) || critter.is_immune_effect( field_fx.get_id() ) ) {
1616 continue;
1617 }
1618 bool effect_added = false;
1619 if( fe.is_environmental ) {
1620 effect_added = critter.add_env_effect( fe.id, fe.bp->token, fe.intensity, fe.get_duration() );
1621 } else {
1622 effect_added = true;
1623 critter.add_effect( field_fx );
1624 }
1625 if( effect_added ) {
1626 critter.add_msg_player_or_npc( fe.env_message_type, fe.get_message(), fe.get_message_npc() );
1627 }
1628 }
1629 }
1630}
bool in_vehicle
Definition: character.h:1536
virtual bool is_monster() const
Definition: creature.h:101
virtual bool is_immune_field(const field_type_id &) const
Returns true if we are immune to the field type with the given fid.
Definition: creature.h:327
virtual void add_msg_player_or_npc(const std::string &, const std::string &) const
Definition: creature.h:681
virtual player * as_player()
Definition: creature.h:122
virtual bool is_immune_effect(const efftype_id &type) const =0
Definition: effect.h:161
const efftype_id & get_id() const
Returns the effect's matching effect_type id.
Definition: effect.h:305
std::vector< field_effect > field_effects() const
Definition: field.cpp:294
bool is_field_alive()
Definition: field.h:89
field_type_id get_field_type() const
Definition: field.cpp:105
A variable sized collection of field entries on a given map square.
Definition: field.h:131
void player_in_field(player &u)
Definition: map_field.cpp:1224
void monster_in_field(monster &z)
Definition: map_field.cpp:1632

References Creature::add_effect(), Creature::add_env_effect(), Creature::add_msg_player_or_npc(), Creature::as_player(), field_entry::field_effects(), get_field(), field_entry::get_field_type(), effect::get_id(), Character::in_vehicle, field_entry::is_field_alive(), Creature::is_immune_effect(), Creature::is_immune_field(), Creature::is_monster(), monster_in_field(), one_in(), player_in_field(), Creature::pos(), Character::pos(), and veh_at().

Referenced by add_field(), game::do_turn(), game::monmove(), npc::move_to(), and game::place_player().

◆ creature_on_trap()

void map::creature_on_trap ( Creature critter,
bool  may_avoid = true 
)

Apply trap effects to the creature, similar to creature_in_field.

If there is no trap at the creatures location, nothing is done. If the creature can avoid the trap, nothing is done as well. Otherwise the trap is triggered.

Parameters
critterCreature that just got trapped
may_avoidIf true, the creature tries to avoid the trap (Creature::avoid_trap). If false, the trap is always triggered.

Definition at line 8546 of file map.cpp.

8547{
8548 const auto &tr = tr_at( c.pos() );
8549 if( tr.is_null() ) {
8550 return;
8551 }
8552 // boarded in a vehicle means the player is above the trap, like a flying monster and can
8553 // never trigger the trap.
8554 const player *const p = dynamic_cast<const player *>( &c );
8555 if( p != nullptr && p->in_vehicle ) {
8556 return;
8557 }
8558 if( may_avoid && c.avoid_trap( c.pos(), tr ) ) {
8559 return;
8560 }
8561 tr.trigger( c.pos(), &c );
8562}

References c, Character::in_vehicle, and tr_at().

Referenced by game::fling_creature(), iexamine::ledge(), npc::move_to(), game::phasing_move(), game::place_player(), mattack::ranged_pull(), smash(), and game::vertical_move().

◆ crush()

void map::crush ( const tripoint p)

Definition at line 3730 of file map.cpp.

3731{
3732 player *crushed_player = g->critter_at<player>( p );
3733
3734 if( crushed_player != nullptr ) {
3735 bool player_inside = false;
3736 if( crushed_player->in_vehicle ) {
3737 const optional_vpart_position vp = veh_at( p );
3738 player_inside = vp && vp->is_inside();
3739 }
3740 if( !player_inside ) { //If there's a player at p and he's not in a covered vehicle...
3741 //This is the roof coming down on top of us, no chance to dodge
3742 crushed_player->add_msg_player_or_npc( m_bad, _( "You are crushed by the falling debris!" ),
3743 _( "<npcname> is crushed by the falling debris!" ) );
3744 // TODO: Make this depend on the ceiling material
3745 const int dam = rng( 0, 40 );
3746 // Torso and head take the brunt of the blow
3747 crushed_player->deal_damage( nullptr, bodypart_id( "head" ), damage_instance( DT_BASH,
3748 dam * .25 ) );
3749 crushed_player->deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_BASH,
3750 dam * .45 ) );
3751 // Legs take the next most through transferred force
3752 crushed_player->deal_damage( nullptr, bodypart_id( "leg_l" ), damage_instance( DT_BASH,
3753 dam * .10 ) );
3754 crushed_player->deal_damage( nullptr, bodypart_id( "leg_r" ), damage_instance( DT_BASH,
3755 dam * .10 ) );
3756 // Arms take the least
3757 crushed_player->deal_damage( nullptr, bodypart_id( "arm_l" ), damage_instance( DT_BASH,
3758 dam * .05 ) );
3759 crushed_player->deal_damage( nullptr, bodypart_id( "arm_r" ), damage_instance( DT_BASH,
3760 dam * .05 ) );
3761
3762 // Pin whoever got hit
3763 crushed_player->add_effect( effect_crushed, 1_turns, num_bp );
3764 crushed_player->check_dead_state();
3765 }
3766 }
3767
3768 if( monster *const monhit = g->critter_at<monster>( p ) ) {
3769 // 25 ~= 60 * .45 (torso)
3770 monhit->deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_BASH, rng( 0, 25 ) ) );
3771
3772 // Pin whoever got hit
3773 monhit->add_effect( effect_crushed, 1_turns, num_bp );
3774 monhit->check_dead_state();
3775 }
3776
3777 if( const optional_vpart_position vp = veh_at( p ) ) {
3778 // Arbitrary number is better than collapsing house roof crushing APCs
3779 vp->vehicle().damage( vp->part_index(), rng( 100, 1000 ), DT_BASH, false );
3780 }
3781}
int_id< body_part_type > bodypart_id
Definition: bodypart.h:23
@ num_bp
Definition: bodypart.h:52
void check_dead_state()
This function checks the creatures is_dead_state and (if true) calls die.
Definition: creature.cpp:1845
void add_msg_player_or_npc(const std::string &player_msg, const std::string &npc_str) const override
Definition: player.cpp:385
@ m_bad
Definition: enums.h:261
static const efftype_id effect_crushed("crushed")

References _, Creature::add_effect(), player::add_msg_player_or_npc(), Creature::check_dead_state(), Character::deal_damage(), DT_BASH, effect_crushed, g, Character::in_vehicle, m_bad, num_bp, rng(), and veh_at().

Referenced by collapse_at().

◆ dangerous_field_at()

bool map::dangerous_field_at ( const tripoint p)

Definition at line 5458 of file map.cpp.

5459{
5460 for( auto &pr : field_at( p ) ) {
5461 auto &fd = pr.second;
5462 if( fd.is_dangerous() ) {
5463 return true;
5464 }
5465 }
5466 return false;
5467}
const field & field_at(const tripoint &p) const
Get the fields that are here.
Definition: map.cpp:5360

References field_at().

Referenced by are_requirements_nearby(), and generic_multi_activity_locations().

◆ decay_cosmetic_fields()

void map::decay_cosmetic_fields ( const tripoint p,
const time_duration time_since_last_actualize 
)
protected

Definition at line 7460 of file map.cpp.

7462{
7463 for( auto &pr : field_at( p ) ) {
7464 auto &fd = pr.second;
7465 const time_duration hl = fd.get_field_type().obj().half_life;
7466 if( !fd.decays_on_actualize() || hl <= 0_turns ) {
7467 continue;
7468 }
7469
7470 const time_duration added_age = 2 * time_since_last_actualize / rng( 2, 4 );
7471 fd.mod_field_age( added_age );
7472 const int intensity_drop = fd.get_field_age() / hl;
7473 if( intensity_drop > 0 ) {
7474 fd.set_field_intensity( fd.get_field_intensity() - intensity_drop );
7475 fd.mod_field_age( -hl * intensity_drop );
7476 }
7477 }
7478}

References field_at(), and rng().

Referenced by actualize().

◆ decay_fields_and_scent()

void map::decay_fields_and_scent ( const time_duration amount)

Moved here from weather.cpp for speed.

Decays fire, washable fields and scent. Washable fields are decayed only by 1/3 of the amount fire is.

Definition at line 2732 of file map.cpp.

2733{
2734 // TODO: Make this happen on all z-levels
2735
2736 // Decay scent separately, so that later we can use field count to skip empty submaps
2737 g->scent.decay();
2738
2739 // Coordinate code copied from lightmap calculations
2740 // TODO: Z
2741 const int smz = abs_sub.z;
2742 const auto &outside_cache = get_cache_ref( smz ).outside_cache;
2743 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
2744 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
2745 const auto cur_submap = get_submap_at_grid( { smx, smy, smz } );
2746 int to_proc = cur_submap->field_count;
2747 if( to_proc < 1 ) {
2748 if( to_proc < 0 ) {
2749 cur_submap->field_count = 0;
2750 dbg( DL::Error ) << "map::decay_fields_and_scent: submap at "
2751 << ( abs_sub + tripoint( smx, smy, 0 ) )
2752 << "has " << to_proc << " field_count";
2753 }
2754 get_cache( smz ).field_cache.reset( smx + ( smy * MAPSIZE ) );
2755 // This submap has no fields
2756 continue;
2757 }
2758
2759 for( int sx = 0; sx < SEEX; ++sx ) {
2760 if( to_proc < 1 ) {
2761 // This submap had some fields, but all got proc'd already
2762 break;
2763 }
2764
2765 for( int sy = 0; sy < SEEY; ++sy ) {
2766 const int x = sx + smx * SEEX;
2767 const int y = sy + smy * SEEY;
2768
2769 field &fields = cur_submap->get_field( { sx, sy} );
2770 if( !outside_cache[x][y] ) {
2771 to_proc -= fields.field_count();
2772 continue;
2773 }
2774
2775 for( auto &fp : fields ) {
2776 to_proc--;
2777 field_entry &cur = fp.second;
2778 const field_type_id type = cur.get_field_type();
2779 const int decay_amount_factor = type.obj().decay_amount_factor;
2780 if( decay_amount_factor != 0 ) {
2781 const time_duration decay_amount = amount / decay_amount_factor;
2782 cur.set_field_age( cur.get_field_age() + decay_amount );
2783 }
2784 }
2785 }
2786 }
2787
2788 if( to_proc > 0 ) {
2789 cur_submap->field_count = cur_submap->field_count - to_proc;
2790 dbg( DL::Error ) << "map::decay_fields_and_scent: submap at "
2791 << abs_sub + tripoint( smx, smy, 0 )
2792 << "has " << cur_submap->field_count - to_proc << "fields, but "
2793 << cur_submap->field_count << " field_count";
2794 }
2795 }
2796 }
2797}
time_duration set_field_age(const time_duration &new_age)
Sets age to the given value.
Definition: field.cpp:138
time_duration get_field_age() const
Definition: field.cpp:133
@ Error
Error (default: enabled).

References abs_sub, dbg, Error, level_cache::field_cache, submap::field_count, g, get_cache(), get_cache_ref(), field_entry::get_field_age(), field_entry::get_field_type(), get_submap_at_grid(), MAPSIZE, my_MAPSIZE, level_cache::outside_cache, SEEX, SEEY, field_entry::set_field_age(), sx, sy, type, and tripoint::z.

◆ delete_graffiti()

void map::delete_graffiti ( const tripoint p)

Definition at line 7887 of file map.cpp.

7888{
7889 if( !inbounds( p ) ) {
7890 return;
7891 }
7892 point l;
7893 submap *const current_submap = get_submap_at( p, l );
7894 current_submap->delete_graffiti( l );
7895}
void delete_graffiti(point p)
Definition: submap.cpp:144

References submap::delete_graffiti(), get_submap_at(), and inbounds().

◆ delete_signage()

void map::delete_signage ( const tripoint p) const

Definition at line 4081 of file map.cpp.

4082{
4083 if( !inbounds( p ) ) {
4084 return;
4085 }
4086
4087 point l;
4088 submap *const current_submap = get_submap_at( p, l );
4089
4090 current_submap->delete_signage( l );
4091}
void delete_signage(point p)
Definition: submap.cpp:183

References submap::delete_signage(), get_submap_at(), and inbounds().

Referenced by bash_furn_success(), construct::done_deconstruct(), and talk_function::loot_building().

◆ deregister_vehicle_zone()

bool map::deregister_vehicle_zone ( zone_data zone)

Definition at line 1021 of file map.cpp.

1022{
1024 zone.get_start_point() ) ).part_with_feature( "CARGO", false ) ) {
1025 auto bounds = vp->vehicle().loot_zones.equal_range( vp->mount() );
1026 for( auto it = bounds.first; it != bounds.second; it++ ) {
1027 if( &zone == &( it->second ) ) {
1028 vp->vehicle().loot_zones.erase( it );
1029 return true;
1030 }
1031 }
1032 }
1033 return false;
1034}
tripoint getlocal(const tripoint &p) const
Inverse of getabs.
Definition: map.cpp:8340
tripoint get_start_point() const
Definition: clzones.h:314

References zone_data::get_start_point(), getlocal(), optional_vpart_position::part_with_feature(), and veh_at().

◆ destroy()

void map::destroy ( const tripoint p,
bool  silent = false 
)

Keeps bashing a square until it can't be bashed anymore.

Definition at line 3696 of file map.cpp.

3697{
3698 // Break if it takes more than 25 destructions to remove to prevent infinite loops
3699 // Example: A bashes to B, B bashes to A leads to A->B->A->...
3700
3701 // If we were destroying a floor, allow destroying floors
3702 // If we were destroying something unpassable, destroy only that
3703 bool was_impassable = impassable( p );
3704 int count = 0;
3705 while( count <= 25
3706 && bash( p, 999, silent, true ).success
3707 && ( !was_impassable || impassable( p ) ) ) {
3708 count++;
3709 }
3710}

References bash(), detail::count(), impassable(), silent, and behavior::success.

Referenced by add_vehicle_to_map(), bash(), MapExtras::burned_ground_parser(), activity_handlers::burrow_finish(), collapse_at(), draw_lab(), activity_handlers::jackhammer_finish(), make_rubble(), MapExtras::mx_crater(), MapExtras::mx_helicopter(), MapExtras::mx_supplydrop(), om_cutdown_trees(), activity_handlers::pickaxe_finish(), process_fields_in_submap(), and explosion_handler::explosion_funcs::resonance_cascade().

◆ destroy_furn()

void map::destroy_furn ( const tripoint p,
bool  silent = false 
)

Keeps bashing a square until there is no more furniture.

Definition at line 3712 of file map.cpp.

3713{
3714 // Break if it takes more than 25 destructions to remove to prevent infinite loops
3715 // Example: A bashes to B, B bashes to A leads to A->B->A->...
3716 int count = 0;
3717 while( count <= 25 && furn( p ) != f_null && bash( p, 999, silent, true ).success ) {
3718 count++;
3719 }
3720}

References bash(), detail::count(), f_null, furn(), silent, and behavior::success.

Referenced by construct::done_grave(), and make_rubble().

◆ destroy_vehicle()

◆ detach_vehicle()

std::unique_ptr< vehicle > map::detach_vehicle ( vehicle veh)

Definition at line 412 of file map.cpp.

413{
414 if( veh == nullptr ) {
415 debugmsg( "map::detach_vehicle was passed nullptr" );
416 return std::unique_ptr<vehicle>();
417 }
418
419 int z = veh->sm_pos.z;
420 if( z < -OVERMAP_DEPTH || z > OVERMAP_HEIGHT ) {
421 debugmsg( "detach_vehicle got a vehicle outside allowed z-level range! name=%s, submap:%d,%d,%d",
422 veh->name, veh->sm_pos.x, veh->sm_pos.y, veh->sm_pos.z );
423 // Try to fix by moving the vehicle here
424 z = veh->sm_pos.z = abs_sub.z;
425 }
426
427 // Unboard all passengers before detaching
428 for( auto const &part : veh->get_avail_parts( VPFLAG_BOARDABLE ) ) {
429 player *passenger = part.get_passenger();
430 if( passenger ) {
431 unboard_vehicle( part, passenger );
432 }
433 }
434 veh->invalidate_towing( true );
435 submap *const current_submap = get_submap_at_grid( veh->sm_pos );
436 level_cache &ch = get_cache( z );
437 for( size_t i = 0; i < current_submap->vehicles.size(); i++ ) {
438 if( current_submap->vehicles[i].get() == veh ) {
439 ch.vehicle_list.erase( veh );
440 ch.zone_vehicles.erase( veh );
442 std::unique_ptr<vehicle> result = std::move( current_submap->vehicles[i] );
443 current_submap->vehicles.erase( current_submap->vehicles.begin() + i );
444 if( veh->tracking_on ) {
446 }
447 dirty_vehicle_list.erase( veh );
448 veh->detach();
449 veh->refresh_position();
450 return result;
451 }
452 }
453 debugmsg( "detach_vehicle can't find it! name=%s, submap:%d,%d,%d", veh->name, veh->sm_pos.x,
454 veh->sm_pos.y, veh->sm_pos.z );
455 return std::unique_ptr<vehicle>();
456}
std::set< vehicle * > dirty_vehicle_list
Definition: map.h:1586
void reset_vehicle_cache()
Definition: map.cpp:312
void remove_vehicle(const vehicle *veh)
Remove the vehicle from being tracked in the overmap.
std::string name
Definition: vehicle.h:1874
void refresh_position()
Definition: vehicle.cpp:5817
bool tracking_on
Definition: vehicle.h:2016
void invalidate_towing(bool first_vehicle=false)
Definition: vehicle.cpp:6131
void detach()
Definition: vehicle.h:769
std::set< vehicle * > zone_vehicles
Definition: map.h:358
std::set< vehicle * > vehicle_list
Definition: map.h:357

References abs_sub, debugmsg, vehicle::detach(), dirty_vehicle_list, vehicle::get_avail_parts(), get_cache(), get_submap_at_grid(), vehicle::invalidate_towing(), avatar_action::move(), vehicle::name, overmap_buffer, OVERMAP_HEIGHT, vehicle::refresh_position(), overmapbuffer::remove_vehicle(), reset_vehicle_cache(), vehicle::sm_pos, vehicle::tracking_on, unboard_vehicle(), level_cache::vehicle_list, submap::vehicles, VPFLAG_BOARDABLE, tripoint::x, tripoint::y, tripoint::z, and level_cache::zone_vehicles.

Referenced by add_vehicle_to_map(), destroy_vehicle(), and editmap::mapgen_veh_destroy().

◆ determine_wall_corner()

int map::determine_wall_corner ( const tripoint p) const
private

Definition at line 7918 of file map.cpp.

7919{
7920 int test_connect_group = ter( p ).obj().connect_group;
7921 uint8_t connections = get_known_connections( p, test_connect_group );
7922 // The bits in connections are SEWN, whereas the characters in LINE_
7923 // constants are NESW, so we want values in 8 | 2 | 1 | 4 order.
7924 switch( connections ) {
7925 case 8 | 2 | 1 | 4:
7926 return LINE_XXXX;
7927 case 0 | 2 | 1 | 4:
7928 return LINE_OXXX;
7929
7930 case 8 | 0 | 1 | 4:
7931 return LINE_XOXX;
7932 case 0 | 0 | 1 | 4:
7933 return LINE_OOXX;
7934
7935 case 8 | 2 | 0 | 4:
7936 return LINE_XXOX;
7937 case 0 | 2 | 0 | 4:
7938 return LINE_OXOX;
7939 case 8 | 0 | 0 | 4:
7940 return LINE_XOOX;
7941 case 0 | 0 | 0 | 4:
7942 return LINE_OXOX; // LINE_OOOX would be better
7943
7944 case 8 | 2 | 1 | 0:
7945 return LINE_XXXO;
7946 case 0 | 2 | 1 | 0:
7947 return LINE_OXXO;
7948 case 8 | 0 | 1 | 0:
7949 return LINE_XOXO;
7950 case 0 | 0 | 1 | 0:
7951 return LINE_XOXO; // LINE_OOXO would be better
7952 case 8 | 2 | 0 | 0:
7953 return LINE_XXOO;
7954 case 0 | 2 | 0 | 0:
7955 return LINE_OXOX; // LINE_OXOO would be better
7956 case 8 | 0 | 0 | 0:
7957 return LINE_XOXO; // LINE_XOOO would be better
7958
7959 case 0 | 0 | 0 | 0:
7960 return ter( p ).obj().symbol(); // technically just a column
7961
7962 default:
7963 // assert( false );
7964 // this shall not happen
7965 return '?';
7966 }
7967}
uint8_t get_known_connections(const tripoint &p, int connect_group, const std::map< tripoint, ter_id > &override={}) const
Definition: map.cpp:1568
generic_factory< overmap_connection > connections("overmap connection")
#define LINE_XOXX
Definition: output.h:47
#define LINE_XOXO
Definition: output.h:39
#define LINE_OXOX
Definition: output.h:40
#define LINE_OOXX
Definition: output.h:43
#define LINE_OXXX
Definition: output.h:48
#define LINE_XXXO
Definition: output.h:45
#define LINE_XXOX
Definition: output.h:46
#define LINE_OXXO
Definition: output.h:42
#define LINE_XOOX
Definition: output.h:44
#define LINE_XXOO
Definition: output.h:41
#define LINE_XXXX
Definition: output.h:49
int symbol() const
Definition: mapdata.cpp:552

References map_data_common_t::connect_group, anonymous_namespace{overmap_connection.cpp}::connections, get_known_connections(), LINE_OOXX, LINE_OXOX, LINE_OXXO, LINE_OXXX, LINE_XOOX, LINE_XOXO, LINE_XOXX, LINE_XXOO, LINE_XXOX, LINE_XXXO, LINE_XXXX, int_id< T >::obj(), map_data_common_t::symbol(), and ter().

Referenced by draw_from_above(), and draw_maptile().

◆ disarm_trap()

void map::disarm_trap ( const tripoint p)
Perception increases chance of disarming trap Dexterity increases chance of disarming trap Traps increases chance of disarming trap

Definition at line 5276 of file map.cpp.

5277{
5278 const trap &tr = tr_at( p );
5279 if( tr.is_null() ) {
5280 debugmsg( "Tried to disarm a trap where there was none (%d %d %d)", p.x, p.y, p.z );
5281 return;
5282 }
5283
5284 const int tSkillLevel = g->u.get_skill_level( skill_traps );
5285 const int diff = tr.get_difficulty();
5286 int roll = rng( tSkillLevel, 4 * tSkillLevel );
5287
5288 // Some traps are not actual traps. Skip the rolls, different message and give the option to grab it right away.
5289 if( tr.get_avoidance() == 0 && tr.get_difficulty() == 0 ) {
5290 add_msg( _( "The %s is taken down." ), tr.name() );
5291 tr.on_disarmed( *this, p );
5292 return;
5293 }
5294
5295 ///\EFFECT_PER increases chance of disarming trap
5296
5297 ///\EFFECT_DEX increases chance of disarming trap
5298
5299 ///\EFFECT_TRAPS increases chance of disarming trap
5300 while( ( rng( 5, 20 ) < g->u.per_cur || rng( 1, 20 ) < g->u.dex_cur ) && roll < 50 ) {
5301 roll++;
5302 }
5303 if( roll >= diff ) {
5304 add_msg( _( "You disarm the trap!" ) );
5305 const int morale_buff = tr.get_avoidance() * 0.4 + tr.get_difficulty() + rng( 0, 4 );
5306 g->u.rem_morale( MORALE_FAILURE );
5307 g->u.add_morale( MORALE_ACCOMPLISHMENT, morale_buff, 40 );
5308 tr.on_disarmed( *this, p );
5309 if( diff > 1.25 * tSkillLevel ) { // failure might have set off trap
5310 g->u.practice( skill_traps, 1.5 * ( diff - tSkillLevel ) );
5311 }
5312 } else if( roll >= diff * .8 ) {
5313 add_msg( _( "You fail to disarm the trap." ) );
5314 const int morale_debuff = -rng( 6, 18 );
5315 g->u.rem_morale( MORALE_ACCOMPLISHMENT );
5316 g->u.add_morale( MORALE_FAILURE, morale_debuff, -40 );
5317 if( diff > 1.25 * tSkillLevel ) {
5318 g->u.practice( skill_traps, 1.5 * ( diff - tSkillLevel ) );
5319 }
5320 } else {
5321 add_msg( m_bad, _( "You fail to disarm the trap, and you set it off!" ) );
5322 const int morale_debuff = -rng( 12, 24 );
5323 g->u.rem_morale( MORALE_ACCOMPLISHMENT );
5324 g->u.add_morale( MORALE_FAILURE, morale_debuff, -40 );
5325 tr.trigger( p, &g->u );
5326 if( diff - roll <= 6 ) {
5327 // Give xp for failing, but not if we failed terribly (in which
5328 // case the trap may not be disarmable).
5329 g->u.practice( skill_traps, 2 * diff );
5330 }
5331 }
5332}
static const skill_id skill_traps("traps")
void add_msg(std::string msg)
Definition: messages.cpp:884
const morale_type MORALE_FAILURE("morale_failure")
const morale_type MORALE_ACCOMPLISHMENT("morale_accomplishment")
Definition: trap.h:86
std::string name() const
Definition: trap.cpp:177
int get_avoidance() const
Whether triggering the trap can be avoid (if greater than 0) and if so, this is compared to dodge ski...
Definition: trap.h:144
void trigger(const tripoint &pos, Creature *creature=nullptr, item *item=nullptr) const
Trigger trap effects.
Definition: trap.cpp:232
bool is_null() const
Whether this is the null-traps, aka no trap at all.
Definition: trap.cpp:245
void on_disarmed(map &m, const tripoint &p) const
Called when a trap at the given point in the map has been disarmed.
Definition: trap.cpp:260
int get_difficulty() const
This is used when disarming the trap.
Definition: trap.h:152

References _, add_msg(), debugmsg, g, trap::get_avoidance(), trap::get_difficulty(), trap::is_null(), m_bad, MORALE_ACCOMPLISHMENT, MORALE_FAILURE, trap::name(), trap::on_disarmed(), rng(), skill_traps, tr_at(), trap::trigger(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by iexamine::trap().

◆ disp_name()

std::string map::disp_name ( const tripoint p)

Definition at line 1388 of file map.cpp.

1389{
1390 return string_format( _( "the %s" ), name( p ) );
1391}

References _, name(), and string_format().

Referenced by vehicle::part_collision().

◆ displace_vehicle()

bool map::displace_vehicle ( vehicle veh,
const tripoint dp 
)

Definition at line 1177 of file map.cpp.

1178{
1179 const tripoint src = veh.global_pos3();
1180
1181 tripoint dst = src + dp;
1182
1183 if( !inbounds( src ) ) {
1184 add_msg( m_debug, "map::displace_vehicle: coordinates out of bounds %d,%d,%d->%d,%d,%d",
1185 src.x, src.y, src.z, dst.x, dst.y, dst.z );
1186 return false;
1187 }
1188
1189 point src_offset;
1190 point dst_offset;
1191 submap *src_submap = get_submap_at( src, src_offset );
1192 submap *dst_submap = get_submap_at( dst, dst_offset );
1193 std::set<int> smzs;
1194
1195 // first, let's find our position in current vehicles vector
1196 size_t our_i = 0;
1197 bool found = false;
1198 for( auto &smap : grid ) {
1199 for( size_t i = 0; i < smap->vehicles.size(); i++ ) {
1200 if( smap->vehicles[i].get() == &veh ) {
1201 our_i = i;
1202 src_submap = smap;
1203 found = true;
1204 break;
1205 }
1206 }
1207 if( found ) {
1208 break;
1209 }
1210 }
1211
1212 if( !found ) {
1213 add_msg( m_debug, "displace_vehicle [%s] failed", veh.name );
1214 return false;
1215 }
1216
1217 // move the vehicle
1218 // don't let it go off grid
1219 if( !inbounds( dst ) ) {
1220 veh.stop();
1221 // Silent debug
1222 dbg( DL::Error ) << "map:displace_vehicle: Stopping vehicle, displaced dp=" << dp;
1223 return true;
1224 }
1225
1226 // Need old coordinates to check for remote control
1227 const bool remote = veh.remote_controlled( g->u );
1228
1229 // record every passenger and pet inside
1230 std::vector<rider_data> riders = veh.get_riders();
1231
1232 bool need_update = false;
1233 bool z_change = false;
1234 int z_to = 0;
1235 // Move passengers and pets
1236 bool complete = false;
1237 // loop until everyone has moved or for each passenger
1238 for( size_t i = 0; !complete && i < riders.size(); i++ ) {
1239 complete = true;
1240 for( rider_data &r : riders ) {
1241 if( r.moved ) {
1242 continue;
1243 }
1244 const int prt = r.prt;
1245
1246 Creature *psg = r.psg;
1247 const tripoint part_pos = veh.global_part_pos3( prt );
1248 if( psg == nullptr ) {
1249 debugmsg( "Empty passenger for part #%d at %d,%d,%d player at %d,%d,%d?",
1250 prt, part_pos.x, part_pos.y, part_pos.z,
1251 g->u.posx(), g->u.posy(), g->u.posz() );
1253 r.moved = true;
1254 continue;
1255 }
1256
1257 if( psg->pos() != part_pos ) {
1258 add_msg( m_debug, "Part/passenger position mismatch: part #%d at %d,%d,%d "
1259 "passenger at %d,%d,%d", prt, part_pos.x, part_pos.y, part_pos.z,
1260 psg->posx(), psg->posy(), psg->posz() );
1261 }
1262 const vehicle_part &veh_part = veh.part( prt );
1263
1264 tripoint next_pos = veh_part.precalc[1];
1265
1266 // Place passenger on the new part location
1267 tripoint psgp( dst + next_pos );
1268 // someone is in the way so try again
1269 if( g->critter_at( psgp ) ) {
1270 complete = false;
1271 continue;
1272 }
1273 if( psg->is_avatar() ) {
1274 // If passenger is you, we need to update the map
1275 need_update = true;
1276 z_change = psgp.z != part_pos.z;
1277 z_to = psgp.z;
1278 }
1279
1280 psg->setpos( psgp );
1281 r.moved = true;
1282 }
1283 }
1284
1285 veh.shed_loose_parts();
1286 smzs = veh.advance_precalc_mounts( dst_offset, src );
1287 if( src_submap != dst_submap ) {
1288 veh.set_submap_moved( tripoint( dst.x / SEEX, dst.y / SEEY, dst.z ) );
1289 auto src_submap_veh_it = src_submap->vehicles.begin() + our_i;
1290 dst_submap->vehicles.push_back( std::move( *src_submap_veh_it ) );
1291 src_submap->vehicles.erase( src_submap_veh_it );
1292 dst_submap->is_uniform = false;
1294 }
1295 if( need_update ) {
1296 g->update_map( g->u );
1297 }
1298 add_vehicle_to_cache( &veh );
1299
1300 if( z_change || src.z != dst.z ) {
1301 if( z_change ) {
1302 g->vertical_shift( z_to );
1303 // vertical moves can flush the caches, so make sure we're still in the cache
1304 add_vehicle_to_cache( &veh );
1305 }
1306 update_vehicle_list( dst_submap, dst.z );
1307 // delete the vehicle from the source z-level vehicle cache set if it is no longer on
1308 // that z-level
1309 if( src.z != dst.z ) {
1310 level_cache &ch2 = get_cache( src.z );
1311 for( const vehicle *elem : ch2.vehicle_list ) {
1312 if( elem == &veh ) {
1313 ch2.vehicle_list.erase( &veh );
1314 ch2.zone_vehicles.erase( &veh );
1315 break;
1316 }
1317 }
1318 }
1320 }
1321
1322 if( remote ) {
1323 // Has to be after update_map or coordinates won't be valid
1324 g->setremoteveh( &veh );
1325 }
1326
1327 //
1328 //global positions of vehicle loot zones have changed.
1329 veh.zones_dirty = true;
1330
1331 for( int vsmz : smzs ) {
1332 on_vehicle_moved( dst.z + vsmz );
1333 }
1334 return true;
1335}
virtual int posy() const =0
virtual int posz() const =0
virtual void setpos(const tripoint &pos)=0
virtual bool is_avatar() const
Definition: creature.h:95
virtual int posx() const =0
void on_vehicle_moved(int smz)
Callback invoked when a vehicle has moved.
Definition: map.cpp:463
void update_vehicle_list(const submap *to, int zlev)
Definition: map.cpp:398
tripoint global_pos3() const
Definition: vehicle.cpp:3282
bool check_is_heli_landed()
std::set< int > advance_precalc_mounts(point new_pos, const tripoint &src)
Definition: vehicle.cpp:7099
void shed_loose_parts()
Definition: vehicle.cpp:6259
std::vector< rider_data > get_riders() const
Definition: vehicle.cpp:3239
void stop(bool update_cache=true)
bool remote_controlled(const Character &p) const
Definition: vehicle.cpp:298
void set_submap_moved(const tripoint &p)
Update the submap coordinates and update the tracker info in the overmap (if enabled).
Definition: vehicle.cpp:3297
bool zones_dirty
Definition: vehicle.h:2032
@ m_debug
Definition: enums.h:271
Structure, describing vehicle part (i.e., wheel, seat)
Definition: vehicle.h:186
std::array< tripoint, 2 > precalc
mount translated to face.dir [0] and turn_dir [1]
Definition: vehicle.h:372
int remove_flag(const int flag) noexcept
Definition: vehicle.h:215

References add_msg(), add_vehicle_to_cache(), vehicle::advance_precalc_mounts(), vehicle::check_is_heli_landed(), dbg, debugmsg, Error, g, get_cache(), vehicle::get_riders(), get_submap_at(), vehicle::global_part_pos3(), vehicle::global_pos3(), grid, inbounds(), invalidate_max_populated_zlev(), Creature::is_avatar(), submap::is_uniform, m_debug, avatar_action::move(), vehicle::name, on_vehicle_moved(), vehicle::part(), vehicle_part::passenger_flag, Creature::pos(), Creature::posx(), Creature::posy(), Creature::posz(), vehicle_part::precalc, vehicle::remote_controlled(), vehicle_part::remove_flag(), SEEX, SEEY, vehicle::set_submap_moved(), Creature::setpos(), vehicle::shed_loose_parts(), vehicle::stop(), update_vehicle_list(), level_cache::vehicle_list, submap::vehicles, tripoint::x, tripoint::y, tripoint::z, level_cache::zone_vehicles, and vehicle::zones_dirty.

Referenced by game::grabbed_veh_move(), and move_vehicle().

◆ displace_water()

bool map::displace_water ( const tripoint dp)

Definition at line 1337 of file map.cpp.

1338{
1339 // Check for shallow water
1340 if( has_flag( "SWIMMABLE", p ) && !has_flag( TFLAG_DEEP_WATER, p ) ) {
1341 int dis_places = 0;
1342 int sel_place = 0;
1343 for( int pass = 0; pass < 2; pass++ ) {
1344 // we do 2 passes.
1345 // first, count how many non-water places around
1346 // then choose one within count and fill it with water on second pass
1347 if( pass != 0 ) {
1348 sel_place = rng( 0, dis_places - 1 );
1349 dis_places = 0;
1350 }
1351 for( const tripoint &temp : points_in_radius( p, 1 ) ) {
1352 if( temp != p
1353 || impassable_ter_furn( temp )
1354 || has_flag( TFLAG_DEEP_WATER, temp ) ) {
1355 continue;
1356 }
1357 ter_id ter0 = ter( temp );
1358 if( ter0 == t_water_sh ||
1359 ter0 == t_water_dp || ter0 == t_water_moving_sh || ter0 == t_water_moving_dp ) {
1360 continue;
1361 }
1362 if( pass != 0 && dis_places == sel_place ) {
1363 ter_set( temp, t_water_sh );
1364 ter_set( temp, t_dirt );
1365 return true;
1366 }
1367
1368 dis_places++;
1369 }
1370 }
1371 }
1372 return false;
1373}
ter_id t_water_moving_dp
Definition: mapdata.cpp:695
ter_id t_water_moving_sh
Definition: mapdata.cpp:695
ter_id t_water_dp
Definition: mapdata.cpp:695
ter_id t_water_sh
Definition: mapdata.cpp:695

References has_flag(), impassable_ter_furn(), points_in_radius(), rng(), t_dirt, t_water_dp, t_water_moving_dp, t_water_moving_sh, t_water_sh, ter(), ter_set(), and TFLAG_DEEP_WATER.

Referenced by move_vehicle().

◆ do_vehicle_caching()

void map::do_vehicle_caching ( int  z)

Definition at line 8273 of file map.cpp.

8274{
8275 level_cache &ch = get_cache( z );
8276 for( vehicle *v : ch.vehicle_list ) {
8277 for( const vpart_reference &vp : v->get_all_parts() ) {
8278 const tripoint &part_pos = v->global_part_pos3( vp.part() );
8279 if( !inbounds( part_pos.xy() ) || vp.part().removed ) {
8280 continue;
8281 }
8282 vehicle_caching_internal( get_cache( part_pos.z ), vp, v );
8283 if( part_pos.z < OVERMAP_HEIGHT ) {
8284 vehicle_caching_internal_above( get_cache( part_pos.z + 1 ), vp, v );
8285 }
8286 }
8287 }
8288}
static void vehicle_caching_internal_above(level_cache &zch_above, const vpart_reference &vp, vehicle *v)
Definition: map.cpp:8264
static void vehicle_caching_internal(level_cache &zch, const vpart_reference &vp, vehicle *v)
Definition: map.cpp:8197

References vehicle::get_all_parts(), get_cache(), vehicle::global_part_pos3(), inbounds(), OVERMAP_HEIGHT, vehicle_caching_internal(), vehicle_caching_internal_above(), level_cache::vehicle_list, tripoint::xy(), and tripoint::z.

Referenced by build_map_cache().

◆ dont_draw_lower_floor()

bool map::dont_draw_lower_floor ( const tripoint p)

Definition at line 5932 of file map.cpp.

5933{
5934 return !zlevels || p.z <= -OVERMAP_DEPTH ||
5936}
@ TFLAG_Z_TRANSPARENT
Definition: mapdata.h:321

References has_flag(), OVERMAP_DEPTH, TFLAG_NO_FLOOR, TFLAG_Z_TRANSPARENT, tripoint::z, and zlevels.

◆ draw()

void map::draw ( const catacurses::window w,
const tripoint center 
)

Draw a visible part of the map into w.

This method uses g->u.posx()/posy() for visibility calculations, so it can not be used for anything but the player's viewport. Likewise, only g->m and maps with equivalent coordinates can be used, as other maps would have coordinate systems incompatible with g->u.posx()

Parameters
wWindow we are drawing in
centerThe coordinate of the center of the viewport, this can be different from the player coordinate.

Definition at line 5773 of file map.cpp.

5774{
5775 // We only need to draw anything if we're not in tiles mode.
5776 if( is_draw_tiles_mode() ) {
5777 return;
5778 }
5779
5780 g->reset_light_level();
5781
5784
5785 const auto &visibility_cache = get_cache_ref( center.z ).visibility_cache;
5786
5787 int wnd_h = getmaxy( w );
5788 int wnd_w = getmaxx( w );
5789 const tripoint offs = center - tripoint( wnd_w / 2, wnd_h / 2, 0 );
5790
5791 // Map memory should be at least the size of the view range
5792 // so that new tiles can be memorized, and at least the size of the terminal
5793 // since displayed area may be bigger than view range.
5794 const point min_mm_reg = point(
5795 std::min( 0, offs.x ),
5796 std::min( 0, offs.y )
5797 );
5798 const point max_mm_reg = point(
5799 std::max( MAPSIZE_X, offs.x + wnd_w ),
5800 std::max( MAPSIZE_Y, offs.y + wnd_h )
5801 );
5802 g->u.prepare_map_memory_region(
5803 g->m.getabs( tripoint( min_mm_reg, center.z ) ),
5804 g->m.getabs( tripoint( max_mm_reg, center.z ) )
5805 );
5806
5807 const auto draw_background = [&]( const tripoint & p ) {
5808 int sym = ' ';
5809 nc_color col = c_black;
5810 if( has_memory_at( p ) ) {
5811 sym = get_memory_at( p );
5812 col = c_brown;
5813 }
5814 wputch( w, col, sym );
5815 };
5816
5817 const auto draw_vision_effect = [&]( const visibility_type vis ) -> bool {
5818 int sym = '#';
5819 nc_color col;
5820 switch( vis )
5821 {
5822 case VIS_LIT:
5823 // can only tell that this square is bright
5824 col = c_light_gray;
5825 break;
5826 case VIS_BOOMER:
5827 col = c_pink;
5828 break;
5829 case VIS_BOOMER_DARK:
5830 col = c_magenta;
5831 break;
5832 default:
5833 return false;
5834 }
5835 wputch( w, col, sym );
5836 return true;
5837 };
5838
5839 drawsq_params params = drawsq_params().memorize( true );
5840 for( int wy = 0; wy < wnd_h; wy++ ) {
5841 for( int wx = 0; wx < wnd_w; wx++ ) {
5842 wmove( w, point( wx, wy ) );
5843 const tripoint p = offs + tripoint( wx, wy, 0 );
5844 if( !inbounds( p ) ) {
5845 draw_background( p );
5846 continue;
5847 }
5848
5849 const lit_level lighting = visibility_cache[p.x][p.y];
5850 const visibility_type vis = get_visibility( lighting, cache );
5851
5852 if( draw_vision_effect( vis ) ) {
5853 continue;
5854 }
5855
5856 if( vis == VIS_HIDDEN || vis == VIS_DARK ) {
5857 draw_background( p );
5858 continue;
5859 }
5860
5861 const maptile curr_maptile = maptile_at_internal( p );
5862 params
5863 .low_light( lighting == lit_level::LOW )
5864 .bright_light( lighting == lit_level::BRIGHT );
5865 if( draw_maptile( w, p, curr_maptile, params ) ) {
5866 continue;
5867 }
5868 const maptile tile_below = maptile_at_internal( p - tripoint_above );
5869 draw_from_above( w, tripoint( p.xy(), p.z - 1 ), tile_below, params );
5870 }
5871 }
5872
5873 // Memorize off-screen tiles
5874 half_open_rectangle<point> display( offs.xy(), offs.xy() + point( wnd_w, wnd_h ) );
5875 drawsq_params mm_params = drawsq_params().memorize( true ).output( false );
5876 for( int y = 0; y < MAPSIZE_Y; y++ ) {
5877 for( int x = 0; x < MAPSIZE_X; x++ ) {
5878 const tripoint p( x, y, center.z );
5879 if( display.contains( p.xy() ) ) {
5880 // Have been memorized during display loop
5881 continue;
5882 }
5883
5884 const lit_level lighting = visibility_cache[p.x][p.y];
5885 const visibility_type vis = get_visibility( lighting, cache );
5886
5887 if( vis != VIS_CLEAR ) {
5888 continue;
5889 }
5890
5891 const maptile curr_maptile = maptile_at_internal( p );
5892 mm_params
5893 .low_light( lighting == lit_level::LOW )
5894 .bright_light( lighting == lit_level::BRIGHT );
5895
5896 draw_maptile( w, p, curr_maptile, mm_params );
5897 }
5898 }
5899}
bool draw_maptile(const catacurses::window &w, const tripoint &p, const maptile &tile, const drawsq_params &params) const
Internal version of the drawsq.
Definition: map.cpp:5938
visibility_type get_visibility(lit_level ll, const visibility_variables &cache) const
Definition: map.cpp:5723
void draw_from_above(const catacurses::window &w, const tripoint &p, const maptile &tile, const drawsq_params &params) const
Draws the tile as seen from above.
Definition: map.cpp:6129
const visibility_variables & get_visibility_variables_cache() const
Definition: map.cpp:5718
void update_visibility_cache(int zlev)
Definition: map.cpp:5669
maptile maptile_at_internal(const tripoint &p) const
Definition: map.cpp:277
#define c_light_gray
Definition: color.h:19
#define c_black
Definition: color.h:17
#define c_magenta
Definition: color.h:25
#define c_brown
Definition: color.h:26
#define c_pink
Definition: color.h:31
visibility_type
Definition: enums.h:57
@ VIS_CLEAR
Definition: enums.h:59
@ VIS_BOOMER
Definition: enums.h:61
@ VIS_DARK
Definition: enums.h:62
@ VIS_BOOMER_DARK
Definition: enums.h:63
@ VIS_HIDDEN
Definition: enums.h:58
@ VIS_LIT
Definition: enums.h:60
lit_level
Definition: lightmap.h:43
static bool has_memory_at(const tripoint &p)
Definition: map.cpp:5756
static int get_memory_at(const tripoint &p)
Definition: map.cpp:5765
void wmove(const window &win, point p)
Definition: ncurses_def.cpp:98
int getmaxx(const window &win)
Definition: ncurses_def.cpp:58
int getmaxy(const window &win)
Definition: ncurses_def.cpp:63
static tripoint_abs_omt display(const tripoint_abs_omt &orig, const draw_data_t &data=draw_data_t())
bool is_draw_tiles_mode()
Check whether we're in tile drawing mode.
Definition: output.cpp:2075
void wputch(const catacurses::window &w, nc_color FG, int ch)
Definition: output.cpp:470
static constexpr tripoint tripoint_above
Definition: point.h:280
Draw parameters used by map::drawsq() and similar methods.
Definition: map.h:180
constexpr drawsq_params & bright_light(bool v)
Whether tile is in bright light.
Definition: map.h:240
constexpr drawsq_params & output(bool v)
HACK: Whether the tile should be printed.
Definition: map.h:269
constexpr drawsq_params & memorize(bool v)
Whether the tile should be memorized.
Definition: map.h:254
constexpr drawsq_params & low_light(bool v)
Whether tile is low light, and should be drawn with muted color.
Definition: map.h:226
lit_level visibility_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:350
A wrapper for a submap point.
Definition: submap.h:238

References BRIGHT, drawsq_params::bright_light(), c_black, c_brown, c_light_gray, c_magenta, c_pink, center, overmap_ui::display(), draw_from_above(), draw_maptile(), g, get_cache_ref(), get_memory_at(), get_visibility(), get_visibility_variables_cache(), catacurses::getmaxx(), catacurses::getmaxy(), has_memory_at(), inbounds(), is_draw_tiles_mode(), LOW, drawsq_params::low_light(), MAPSIZE_X, MAPSIZE_Y, maptile_at_internal(), drawsq_params::memorize(), drawsq_params::output(), tripoint_above, update_visibility_cache(), VIS_BOOMER, VIS_BOOMER_DARK, VIS_CLEAR, VIS_DARK, VIS_HIDDEN, VIS_LIT, level_cache::visibility_cache, catacurses::wmove(), wputch(), tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by advanced_inventory::draw_minimap(), and game::draw_ter().

◆ draw_anthill()

void map::draw_anthill ( mapgendata dat)
protected

Definition at line 5063 of file mapgen.cpp.

5064{
5065 const oter_id &terrain_type = dat.terrain_type();
5066 if( terrain_type == "anthill" || terrain_type == "acid_anthill" ) {
5067 for( int i = 0; i < SEEX * 2; i++ ) {
5068 for( int j = 0; j < SEEY * 2; j++ ) {
5069 if( i < 8 || j < 8 || i > SEEX * 2 - 9 || j > SEEY * 2 - 9 ) {
5070 ter_set( point( i, j ), dat.groundcover() );
5071 } else if( ( i == 11 || i == 12 ) && ( j == 11 || j == 12 ) ) {
5072 ter_set( point( i, j ), t_slope_down );
5073 } else {
5074 ter_set( point( i, j ), t_dirtmound );
5075 }
5076 }
5077 }
5078 }
5079}
const oter_id & terrain_type() const
Definition: mapgendata.h:87
ter_id groundcover()
Definition: mapgendata.cpp:141
ter_id t_slope_down
Definition: mapdata.cpp:720
ter_id t_dirtmound
Definition: mapdata.cpp:627

References mapgendata::groundcover(), SEEX, SEEY, t_dirtmound, t_slope_down, ter_set(), and mapgendata::terrain_type().

Referenced by draw_map().

◆ draw_circle_furn()

void map::draw_circle_furn ( const furn_id type,
point  p,
int  rad 
)

Definition at line 8513 of file map.cpp.

8514{
8515 draw_circle( [this, type]( point q ) {
8516 this->furn_set( q, type );
8517 }, p, rad );
8518}
void draw_circle(std::function< void(point)>set, const rl_vec2d &p, double rad)

References draw_circle(), furn_set(), rad, and type.

Referenced by circle_furn().

◆ draw_circle_ter() [1/2]

void map::draw_circle_ter ( const ter_id type,
const rl_vec2d p,
double  rad 
)

Definition at line 8499 of file map.cpp.

8500{
8501 draw_circle( [this, type]( point q ) {
8502 this->ter_set( q, type );
8503 }, p, rad );
8504}

References draw_circle(), rad, ter_set(), and type.

Referenced by circle().

◆ draw_circle_ter() [2/2]

void map::draw_circle_ter ( const ter_id type,
point  p,
int  rad 
)

Definition at line 8506 of file map.cpp.

8507{
8508 draw_circle( [this, type]( point q ) {
8509 this->ter_set( q, type );
8510 }, p, rad );
8511}

References draw_circle(), rad, ter_set(), and type.

◆ draw_connections()

void map::draw_connections ( mapgendata dat)
protected

Definition at line 5273 of file mapgen.cpp.

5274{
5275 const oter_id &terrain_type = dat.terrain_type();
5276 if( is_ot_match( "subway", terrain_type,
5277 ot_match_type::type ) ) { // FUUUUU it's IF ELIF ELIF ELIF's mini-me =[
5278 if( is_ot_match( "sewer", dat.north(), ot_match_type::type ) &&
5279 !connects_to( terrain_type, 0 ) ) {
5280 if( connects_to( dat.north(), 2 ) ) {
5281 for( int i = SEEX - 2; i < SEEX + 2; i++ ) {
5282 for( int j = 0; j < SEEY; j++ ) {
5283 ter_set( point( i, j ), t_sewage );
5284 }
5285 }
5286 } else {
5287 for( int j = 0; j < 3; j++ ) {
5288 ter_set( point( SEEX, j ), t_rock_floor );
5289 ter_set( point( SEEX - 1, j ), t_rock_floor );
5290 }
5291 ter_set( point( SEEX, 3 ), t_door_metal_c );
5292 ter_set( point( SEEX - 1, 3 ), t_door_metal_c );
5293 }
5294 }
5295 if( is_ot_match( "sewer", dat.east(), ot_match_type::type ) &&
5296 !connects_to( terrain_type, 1 ) ) {
5297 if( connects_to( dat.east(), 3 ) ) {
5298 for( int i = SEEX; i < SEEX * 2; i++ ) {
5299 for( int j = SEEY - 2; j < SEEY + 2; j++ ) {
5300 ter_set( point( i, j ), t_sewage );
5301 }
5302 }
5303 } else {
5304 for( int i = SEEX * 2 - 3; i < SEEX * 2; i++ ) {
5305 ter_set( point( i, SEEY ), t_rock_floor );
5306 ter_set( point( i, SEEY - 1 ), t_rock_floor );
5307 }
5308 ter_set( point( SEEX * 2 - 4, SEEY ), t_door_metal_c );
5309 ter_set( point( SEEX * 2 - 4, SEEY - 1 ), t_door_metal_c );
5310 }
5311 }
5312 if( is_ot_match( "sewer", dat.south(), ot_match_type::type ) &&
5313 !connects_to( terrain_type, 2 ) ) {
5314 if( connects_to( dat.south(), 0 ) ) {
5315 for( int i = SEEX - 2; i < SEEX + 2; i++ ) {
5316 for( int j = SEEY; j < SEEY * 2; j++ ) {
5317 ter_set( point( i, j ), t_sewage );
5318 }
5319 }
5320 } else {
5321 for( int j = SEEY * 2 - 3; j < SEEY * 2; j++ ) {
5322 ter_set( point( SEEX, j ), t_rock_floor );
5323 ter_set( point( SEEX - 1, j ), t_rock_floor );
5324 }
5325 ter_set( point( SEEX, SEEY * 2 - 4 ), t_door_metal_c );
5326 ter_set( point( SEEX - 1, SEEY * 2 - 4 ), t_door_metal_c );
5327 }
5328 }
5329 if( is_ot_match( "sewer", dat.west(), ot_match_type::type ) &&
5330 !connects_to( terrain_type, 3 ) ) {
5331 if( connects_to( dat.west(), 1 ) ) {
5332 for( int i = 0; i < SEEX; i++ ) {
5333 for( int j = SEEY - 2; j < SEEY + 2; j++ ) {
5334 ter_set( point( i, j ), t_sewage );
5335 }
5336 }
5337 } else {
5338 for( int i = 0; i < 3; i++ ) {
5339 ter_set( point( i, SEEY ), t_rock_floor );
5340 ter_set( point( i, SEEY - 1 ), t_rock_floor );
5341 }
5342 ter_set( point( 3, SEEY ), t_door_metal_c );
5343 ter_set( point( 3, SEEY - 1 ), t_door_metal_c );
5344 }
5345 }
5346 } else if( is_ot_match( "sewer", terrain_type, ot_match_type::type ) ) {
5347 if( dat.above() == "road_nesw_manhole" ) {
5348 ter_set( point( rng( SEEX - 2, SEEX + 1 ), rng( SEEY - 2, SEEY + 1 ) ), t_ladder_up );
5349 }
5350 if( is_ot_match( "subway", dat.north(), ot_match_type::type ) &&
5351 !connects_to( terrain_type, 0 ) ) {
5352 for( int j = 0; j < SEEY - 3; j++ ) {
5353 ter_set( point( SEEX, j ), t_rock_floor );
5354 ter_set( point( SEEX - 1, j ), t_rock_floor );
5355 }
5356 ter_set( point( SEEX, SEEY - 3 ), t_door_metal_c );
5357 ter_set( point( SEEX - 1, SEEY - 3 ), t_door_metal_c );
5358 }
5359 if( is_ot_match( "subway", dat.east(), ot_match_type::type ) &&
5360 !connects_to( terrain_type, 1 ) ) {
5361 for( int i = SEEX + 3; i < SEEX * 2; i++ ) {
5362 ter_set( point( i, SEEY ), t_rock_floor );
5363 ter_set( point( i, SEEY - 1 ), t_rock_floor );
5364 }
5365 ter_set( point( SEEX + 2, SEEY ), t_door_metal_c );
5366 ter_set( point( SEEX + 2, SEEY - 1 ), t_door_metal_c );
5367 }
5368 if( is_ot_match( "subway", dat.south(), ot_match_type::type ) &&
5369 !connects_to( terrain_type, 2 ) ) {
5370 for( int j = SEEY + 3; j < SEEY * 2; j++ ) {
5371 ter_set( point( SEEX, j ), t_rock_floor );
5372 ter_set( point( SEEX - 1, j ), t_rock_floor );
5373 }
5374 ter_set( point( SEEX, SEEY + 2 ), t_door_metal_c );
5375 ter_set( point( SEEX - 1, SEEY + 2 ), t_door_metal_c );
5376 }
5377 if( is_ot_match( "subway", dat.west(), ot_match_type::type ) &&
5378 !connects_to( terrain_type, 3 ) ) {
5379 for( int i = 0; i < SEEX - 3; i++ ) {
5380 ter_set( point( i, SEEY ), t_rock_floor );
5381 ter_set( point( i, SEEY - 1 ), t_rock_floor );
5382 }
5383 ter_set( point( SEEX - 3, SEEY ), t_door_metal_c );
5384 ter_set( point( SEEX - 3, SEEY - 1 ), t_door_metal_c );
5385 }
5386 } else if( is_ot_match( "ants", terrain_type, ot_match_type::type ) ) {
5387 if( dat.above() == "anthill" ) {
5388 if( const auto p = random_point( *this, [this]( const tripoint & n ) {
5389 return ter( n ) == t_rock_floor;
5390 } ) ) {
5391 ter_set( *p, t_slope_up );
5392 }
5393 }
5394 }
5395
5396 // finally, any terrain with SIDEWALKS should contribute sidewalks to neighboring diagonal roads
5397 if( terrain_type->has_flag( has_sidewalk ) ) {
5398 for( int dir = 4; dir < 8; dir++ ) { // NE SE SW NW
5399 bool n_roads_nesw[4] = {};
5400 int n_num_dirs = terrain_type_to_nesw_array( oter_id( dat.t_nesw[dir] ), n_roads_nesw );
5401 // only handle diagonal neighbors
5402 if( n_num_dirs == 2 &&
5403 n_roads_nesw[( ( dir - 4 ) + 3 ) % 4] &&
5404 n_roads_nesw[( ( dir - 4 ) + 2 ) % 4] ) {
5405 // make drawing simpler by rotating the map back and forth
5406 rotate( 4 - ( dir - 4 ) );
5407 // draw a small triangle of sidewalk in the northeast corner
5408 for( int y = 0; y < 4; y++ ) {
5409 for( int x = SEEX * 2 - 4; x < SEEX * 2; x++ ) {
5410 if( x - y > SEEX * 2 - 4 ) {
5411 // TODO: more discriminating conditions
5412 if( ter( point( x, y ) ) == t_grass || ter( point( x, y ) ) == t_dirt ||
5413 ter( point( x, y ) ) == t_shrub ) {
5414 ter_set( point( x, y ), t_sidewalk );
5415 }
5416 }
5417 }
5418 }
5419 rotate( ( dir - 4 ) );
5420 }
5421 }
5422 }
5423
5425}
void rotate(int turns, bool setpos_safe=false)
Rotates this map, and all of its contents, by the specified multiple of 90 degrees.
Definition: mapgen.cpp:5835
const oter_id & above() const
Definition: mapgendata.h:131
const oter_id & north() const
Definition: mapgendata.h:107
const oter_id & west() const
Definition: mapgendata.h:116
const oter_id & south() const
Definition: mapgendata.h:113
oter_id t_nesw[8]
Definition: mapgendata.h:45
const oter_id & east() const
Definition: mapgendata.h:110
cata::optional< tripoint > random_point(const map &m, const std::function< bool(const tripoint &)> &predicate)
Same as other random_point with a range enclosing all valid points of the map.
ter_id t_grass
Definition: mapdata.cpp:630
ter_id t_sewage
Definition: mapdata.cpp:696
ter_id t_slope_up
Definition: mapdata.cpp:721
ter_id t_ladder_up
Definition: mapdata.cpp:720
ter_id t_shrub
Definition: mapdata.cpp:685
ter_id t_sidewalk
Definition: mapdata.cpp:632
ter_id t_door_metal_c
Definition: mapdata.cpp:664
bool connects_to(const oter_id &there, int dir)
Definition: mapgen.cpp:5937
void resolve_regional_terrain_and_furniture(const mapgendata &dat)
int terrain_type_to_nesw_array(oter_id terrain_type, bool array[4])
@ has_sidewalk
Definition: omdata.h:90
bool is_ot_match(const std::string &name, const oter_id &oter, const ot_match_type match_type)
Determine if the provided name is a match with the provided overmap terrain based on the specified ma...
Definition: overmap.cpp:568
bool has_flag(oter_flags flag) const
Definition: omdata.h:258

References mapgendata::above(), connects_to(), mapgendata::east(), oter_t::has_flag(), has_sidewalk, is_ot_match(), mapgendata::north(), oter_id, random_point(), resolve_regional_terrain_and_furniture(), rng(), rotate(), SEEX, SEEY, mapgendata::south(), t_dirt, t_door_metal_c, t_grass, t_ladder_up, mapgendata::t_nesw, t_rock_floor, t_sewage, t_shrub, t_sidewalk, t_slope_up, ter(), ter_set(), mapgendata::terrain_type(), terrain_type_to_nesw_array(), type, and mapgendata::west().

Referenced by draw_map().

◆ draw_fill_background() [1/3]

void map::draw_fill_background ( const ter_id type)

Definition at line 8428 of file map.cpp.

8429{
8430 // Need to explicitly set caches dirty - set_ter would do it before
8435
8436 // Fill each submap rather than each tile
8437 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
8438 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
8439 auto sm = get_submap_at_grid( {gridx, gridy} );
8440 sm->is_uniform = true;
8441 sm->set_all_ter( type );
8442 }
8443 }
8444}
void set_outside_cache_dirty(const int zlev)
Definition: map.cpp:220

References abs_sub, get_submap_at_grid(), my_MAPSIZE, set_outside_cache_dirty(), set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_transparency_cache_dirty(), coords::sm, type, and tripoint::z.

Referenced by fill_background(), mapgendata::fill_groundcover(), mapgen_function_json::generate(), and mapgen_forest().

◆ draw_fill_background() [2/3]

void map::draw_fill_background ( const weighted_int_list< ter_id > &  f)

Definition at line 8450 of file map.cpp.

8451{
8453}
void draw_square_ter(const ter_id &type, point p1, point p2)
Definition: map.cpp:8455

References draw_square_ter(), my_MAPSIZE, point_zero, SEEX, and SEEY.

◆ draw_fill_background() [3/3]

void map::draw_fill_background ( ter_id(*)()  f)

Definition at line 8446 of file map.cpp.

8447{
8449}

References draw_square_ter(), my_MAPSIZE, point_zero, SEEX, and SEEY.

◆ draw_from_above()

void map::draw_from_above ( const catacurses::window w,
const tripoint p,
const maptile tile,
const drawsq_params params 
) const
private

Draws the tile as seen from above.

Definition at line 6129 of file map.cpp.

6131{
6132 static const int AUTO_WALL_PLACEHOLDER = 2; // this should never appear as a real symbol!
6133
6134 nc_color tercol = c_dark_gray;
6135 int sym = ' ';
6136
6137 const ter_t &curr_ter = curr_tile.get_ter_t();
6138 const furn_t &curr_furn = curr_tile.get_furn_t();
6139 int part_below;
6140 const vehicle *veh;
6141 if( curr_furn.has_flag( TFLAG_SEEN_FROM_ABOVE ) ) {
6142 sym = curr_furn.symbol();
6143 tercol = curr_furn.color();
6144 } else if( curr_furn.movecost < 0 ) {
6145 sym = '.';
6146 tercol = curr_furn.color();
6147 } else if( ( veh = veh_at_internal( p, part_below ) ) != nullptr ) {
6148 const int roof = veh->roof_at_part( part_below );
6149 const int displayed_part = roof >= 0 ? roof : part_below;
6150 sym = special_symbol( veh->face.dir_symbol( veh->part_sym( displayed_part, true ) ) );
6151 tercol = ( roof >= 0 ||
6152 vpart_position( const_cast<vehicle &>( *veh ),
6153 part_below ).obstacle_at_part() ) ? c_light_gray : c_light_gray_cyan;
6154 } else if( curr_ter.has_flag( TFLAG_SEEN_FROM_ABOVE ) ) {
6155 if( curr_ter.has_flag( TFLAG_AUTO_WALL_SYMBOL ) ) {
6156 sym = AUTO_WALL_PLACEHOLDER;
6157 } else if( curr_ter.has_flag( TFLAG_RAMP ) ) {
6158 sym = '>';
6159 } else {
6160 sym = curr_ter.symbol();
6161 }
6162 tercol = curr_ter.color();
6163 } else if( curr_ter.movecost == 0 ) {
6164 sym = '.';
6165 tercol = curr_ter.color();
6166 } else if( !curr_ter.has_flag( TFLAG_NO_FLOOR ) ) {
6167 sym = '.';
6168 if( curr_ter.color() != c_cyan ) {
6169 // Need a special case here, it doesn't cyanize well
6170 tercol = cyan_background( curr_ter.color() );
6171 } else {
6172 tercol = c_black_cyan;
6173 }
6174 } else {
6175 sym = curr_ter.symbol();
6176 tercol = curr_ter.color();
6177 }
6178
6179 if( sym == AUTO_WALL_PLACEHOLDER ) {
6180 sym = determine_wall_corner( p );
6181 }
6182
6183 const auto u_vision = g->u.get_vision_modes();
6184 if( u_vision[BOOMERED] ) {
6185 tercol = c_magenta;
6186 } else if( u_vision[NV_GOGGLES] ) {
6187 tercol = params.bright_light() ? c_white : c_light_green;
6188 } else if( params.low_light() ) {
6189 tercol = c_dark_gray;
6190 } else if( u_vision[DARKNESS] ) {
6191 tercol = c_dark_gray;
6192 }
6193
6194 if( params.highlight() ) {
6195 tercol = invert_color( tercol );
6196 }
6197
6198 if( params.output() ) {
6199 wputch( w, tercol, sym );
6200 }
6201}
@ DARKNESS
Definition: character.h:92
@ NV_GOGGLES
Definition: character.h:88
@ BOOMERED
Definition: character.h:91
int determine_wall_corner(const tripoint &p) const
Definition: map.cpp:7918
vehicle * veh_at_internal(const tripoint &p, int &part_num)
Definition: map.cpp:1102
int dir_symbol(int sym) const
Definition: tileray.cpp:113
char part_sym(int p, bool exact=false) const
int roof_at_part(int p) const
Definition: vehicle.cpp:3013
tileray face
Definition: vehicle.h:1973
cata::optional< vpart_reference > obstacle_at_part() const
Returns the obstacle that exists at this point of the vehicle (if any).
Definition: vehicle.cpp:2439
nc_color invert_color(const nc_color &c)
Definition: color.cpp:503
nc_color cyan_background(const nc_color &c)
Definition: color.cpp:545
#define c_white
Definition: color.h:18
#define c_light_green
Definition: color.h:28
#define c_dark_gray
Definition: color.h:20
#define c_black_cyan
Definition: color.h:154
#define c_cyan
Definition: color.h:24
#define c_light_gray_cyan
Definition: color.h:156
@ TFLAG_AUTO_WALL_SYMBOL
Definition: mapdata.h:305
@ TFLAG_SEEN_FROM_ABOVE
Definition: mapdata.h:311
int special_symbol(int sym)
Definition: output.cpp:1095
constexpr drawsq_params & highlight(bool v)
Highlight the tile.
Definition: map.h:198
nc_color color() const
Definition: mapdata.cpp:557

References BOOMERED, drawsq_params::bright_light(), c_black_cyan, c_cyan, c_dark_gray, c_light_gray, c_light_gray_cyan, c_light_green, c_magenta, c_white, map_data_common_t::color(), cyan_background(), DARKNESS, determine_wall_corner(), tileray::dir_symbol(), vehicle::face, g, maptile::get_furn_t(), maptile::get_ter_t(), map_data_common_t::has_flag(), drawsq_params::highlight(), invert_color(), drawsq_params::low_light(), map_data_common_t::movecost, NV_GOGGLES, vpart_position::obstacle_at_part(), drawsq_params::output(), vehicle::part_sym(), vehicle::roof_at_part(), special_symbol(), map_data_common_t::symbol(), TFLAG_AUTO_WALL_SYMBOL, TFLAG_NO_FLOOR, TFLAG_RAMP, TFLAG_SEEN_FROM_ABOVE, veh_at_internal(), and wputch().

Referenced by draw(), and drawsq().

◆ draw_lab()

void map::draw_lab ( mapgendata dat)
protected

Definition at line 3546 of file mapgen.cpp.

3547{
3548 const oter_id &terrain_type = dat.terrain_type();
3549 // To distinguish between types of labs
3550 bool ice_lab = true;
3551 bool central_lab = false;
3552 bool tower_lab = false;
3553
3554 point p2;
3555
3556 int lw = 0;
3557 int rw = 0;
3558 int tw = 0;
3559 int bw = 0;
3560
3561 if( terrain_type == "lab" || terrain_type == "lab_stairs" || terrain_type == "lab_core" ||
3562 terrain_type == "ants_lab" || terrain_type == "ants_lab_stairs" ||
3563 terrain_type == "ice_lab" || terrain_type == "ice_lab_stairs" ||
3564 terrain_type == "ice_lab_core" ||
3565 terrain_type == "central_lab" || terrain_type == "central_lab_stairs" ||
3566 terrain_type == "central_lab_core" ||
3567 terrain_type == "tower_lab" || terrain_type == "tower_lab_stairs" ) {
3568
3569 ice_lab = is_ot_match( "ice_lab", terrain_type, ot_match_type::prefix );
3570 central_lab = is_ot_match( "central_lab", terrain_type, ot_match_type::prefix );
3571 tower_lab = is_ot_match( "tower_lab", terrain_type, ot_match_type::prefix );
3572
3573 if( ice_lab ) {
3574 int temperature = -20 + 30 * ( dat.zlevel() );
3576 set_temperature( p2 + point( SEEX, 0 ), temperature );
3577 set_temperature( p2 + point( 0, SEEY ), temperature );
3579 }
3580
3581 // Check for adjacent sewers; used below
3582 tw = 0;
3583 rw = 0;
3584 bw = 0;
3585 lw = 0;
3586 if( is_ot_match( "sewer", dat.north(), ot_match_type::type ) && connects_to( dat.north(), 2 ) ) {
3587 tw = SOUTH_EDGE + 1;
3588 }
3589 if( is_ot_match( "sewer", dat.east(), ot_match_type::type ) && connects_to( dat.east(), 3 ) ) {
3590 rw = EAST_EDGE + 1;
3591 }
3592 if( is_ot_match( "sewer", dat.south(), ot_match_type::type ) && connects_to( dat.south(), 0 ) ) {
3593 bw = SOUTH_EDGE + 1;
3594 }
3595 if( is_ot_match( "sewer", dat.west(), ot_match_type::type ) && connects_to( dat.west(), 1 ) ) {
3596 lw = EAST_EDGE + 1;
3597 }
3598 if( dat.zlevel() == 0 ) { // We're on ground level
3599 for( int i = 0; i < SEEX * 2; i++ ) {
3600 for( int j = 0; j < SEEY * 2; j++ ) {
3601 if( i <= 1 || i >= SEEX * 2 - 2 ||
3602 ( j > 1 && j < SEEY * 2 - 2 && ( i == SEEX - 2 || i == SEEX + 1 ) ) ) {
3603 ter_set( point( i, j ), t_concrete_wall );
3604 } else if( j <= 1 || j >= SEEY * 2 - 2 ) {
3605 ter_set( point( i, j ), t_concrete_wall );
3606 } else {
3607 ter_set( point( i, j ), t_floor );
3608 }
3609 }
3610 }
3611 ter_set( point( SEEX - 1, 0 ), t_door_metal_locked );
3612 ter_set( point( SEEX - 1, 1 ), t_floor );
3614 ter_set( point( SEEX, 1 ), t_floor );
3615 ter_set( point( SEEX - 2 + rng( 0, 1 ) * 3, 0 ), t_card_science );
3616 ter_set( point( SEEX - 2, SEEY ), t_door_metal_c );
3617 ter_set( point( SEEX + 1, SEEY ), t_door_metal_c );
3618 ter_set( point( SEEX - 2, SEEY - 1 ), t_door_metal_c );
3619 ter_set( point( SEEX + 1, SEEY - 1 ), t_door_metal_c );
3620 ter_set( point( SEEX - 1, SEEY * 2 - 3 ), t_stairs_down );
3621 ter_set( point( SEEX, SEEY * 2 - 3 ), t_stairs_down );
3622 science_room( this, point( 2, 2 ), point( SEEX - 3, SEEY * 2 - 3 ), dat.zlevel(), 1 );
3623 science_room( this, point( SEEX + 2, 2 ), point( SEEX * 2 - 3, SEEY * 2 - 3 ), dat.zlevel(), 3 );
3624
3625 place_spawns( GROUP_TURRET, 1, point( SEEX, 5 ), point( SEEX, 5 ), 1, true );
3626
3627 if( is_ot_match( "road", dat.east(), ot_match_type::type ) ) {
3628 rotate( 1 );
3629 } else if( is_ot_match( "road", dat.south(), ot_match_type::type ) ) {
3630 rotate( 2 );
3631 } else if( is_ot_match( "road", dat.west(), ot_match_type::type ) ) {
3632 rotate( 3 );
3633 }
3634 } else if( tw != 0 || rw != 0 || lw != 0 || bw != 0 ) { // Sewers!
3635 for( int i = 0; i < SEEX * 2; i++ ) {
3636 for( int j = 0; j < SEEY * 2; j++ ) {
3637 ter_set( point( i, j ), t_thconc_floor );
3638 if( ( ( i < lw || i > EAST_EDGE - rw ) && j > SEEY - 3 && j < SEEY + 2 ) ||
3639 ( ( j < tw || j > SOUTH_EDGE - bw ) && i > SEEX - 3 && i < SEEX + 2 ) ) {
3640 ter_set( point( i, j ), t_sewage );
3641 }
3642 if( ( i == 0 && is_ot_match( "lab", dat.east(), ot_match_type::contains ) ) || i == EAST_EDGE ) {
3643 if( ter( point( i, j ) ) == t_sewage ) {
3644 ter_set( point( i, j ), t_bars );
3645 } else if( j == SEEY - 1 || j == SEEY ) {
3646 ter_set( point( i, j ), t_door_metal_c );
3647 } else {
3648 ter_set( point( i, j ), t_concrete_wall );
3649 }
3650 } else if( ( j == 0 && is_ot_match( "lab", dat.north(), ot_match_type::contains ) ) ||
3651 j == SOUTH_EDGE ) {
3652 if( ter( point( i, j ) ) == t_sewage ) {
3653 ter_set( point( i, j ), t_bars );
3654 } else if( i == SEEX - 1 || i == SEEX ) {
3655 ter_set( point( i, j ), t_door_metal_c );
3656 } else {
3657 ter_set( point( i, j ), t_concrete_wall );
3658 }
3659 }
3660 }
3661 }
3662 } else { // We're below ground, and no sewers
3663 // Set up the boundaries of walls (connect to adjacent lab squares)
3664 tw = is_ot_match( "lab", dat.north(), ot_match_type::contains ) ? 0 : 2;
3665 rw = is_ot_match( "lab", dat.east(), ot_match_type::contains ) ? 1 : 2;
3666 bw = is_ot_match( "lab", dat.south(), ot_match_type::contains ) ? 1 : 2;
3667 lw = is_ot_match( "lab", dat.west(), ot_match_type::contains ) ? 0 : 2;
3668
3669 int boarders = 0;
3670 if( tw == 0 ) {
3671 boarders++;
3672 }
3673 if( rw == 1 ) {
3674 boarders++;
3675 }
3676 if( bw == 1 ) {
3677 boarders++;
3678 }
3679 if( lw == 0 ) {
3680 boarders++;
3681 }
3682
3683 const auto maybe_insert_stairs = [this]( const oter_id & terrain, const ter_id & t_stair_type ) {
3684 if( is_ot_match( "stairs", terrain, ot_match_type::contains ) ) {
3685 const auto predicate = [this]( const tripoint & p ) {
3686 return ter( p ) == t_thconc_floor && furn( p ) == f_null && tr_at( p ).is_null();
3687 };
3688 const auto range = points_in_rectangle( { 0, 0, abs_sub.z }, { SEEX * 2 - 2, SEEY * 2 - 2, abs_sub.z } );
3689
3690 if( const auto p = random_point( range, predicate ) ) {
3691 ter_set( *p, t_stair_type );
3692 }
3693 }
3694 };
3695
3696 //A lab area with only one entrance
3697 if( boarders == 1 ) {
3698 // If you remove the usage of "lab_1side" here, remove it from mapgen_factory::get_usages above as well.
3699 if( oter_mapgen.generate( dat, "lab_1side" ) ) {
3700 if( tw == 2 ) {
3701 rotate( 2 );
3702 }
3703 if( rw == 2 ) {
3704 rotate( 1 );
3705 }
3706 if( lw == 2 ) {
3707 rotate( 3 );
3708 }
3709 } else {
3710 debugmsg( "Error: Tried to generate 1-sided lab but no lab_1side json exists." );
3711 }
3712 maybe_insert_stairs( dat.above(), t_stairs_up );
3713 maybe_insert_stairs( terrain_type, t_stairs_down );
3714 } else {
3715 const int hardcoded_4side_map_weight = 1500; // weight of all hardcoded maps.
3716 // If you remove the usage of "lab_4side" here, remove it from mapgen_factory::get_usages above as well.
3717 if( oter_mapgen.generate( dat, "lab_4side", hardcoded_4side_map_weight ) ) {
3718 // If the map template hasn't handled borders, handle them in code.
3719 // Rotated maps cannot handle borders and have to be caught in code.
3720 // We determine if a border isn't handled by checking the east-facing
3721 // border space where the door normally is -- it should be a wall or door.
3722 tripoint east_border( 23, 11, abs_sub.z );
3723 if( !has_flag_ter( "WALL", east_border ) &&
3724 !has_flag_ter( "DOOR", east_border ) ) {
3725 // TODO: create a ter_reset function that does ter_set,
3726 // furn_set, and i_clear?
3727 ter_id lw_type = tower_lab ? t_reinforced_glass : t_concrete_wall;
3728 ter_id tw_type = tower_lab ? t_reinforced_glass : t_concrete_wall;
3729 ter_id rw_type = tower_lab && rw == 2 ? t_reinforced_glass :
3731 ter_id bw_type = tower_lab && bw == 2 ? t_reinforced_glass :
3733 for( int i = 0; i < SEEX * 2; i++ ) {
3734 ter_set( point( 23, i ), rw_type );
3735 furn_set( point( 23, i ), f_null );
3736 i_clear( tripoint( 23, i, get_abs_sub().z ) );
3737
3738 ter_set( point( i, 23 ), bw_type );
3739 furn_set( point( i, 23 ), f_null );
3740 i_clear( tripoint( i, 23, get_abs_sub().z ) );
3741
3742 if( lw == 2 ) {
3743 ter_set( point( 0, i ), lw_type );
3744 furn_set( point( 0, i ), f_null );
3745 i_clear( tripoint( 0, i, get_abs_sub().z ) );
3746 }
3747 if( tw == 2 ) {
3748 ter_set( point( i, 0 ), tw_type );
3749 furn_set( point( i, 0 ), f_null );
3750 i_clear( tripoint( i, 0, get_abs_sub().z ) );
3751 }
3752 }
3753 if( rw != 2 ) {
3754 ter_set( point( 23, 11 ), t_door_metal_c );
3755 ter_set( point( 23, 12 ), t_door_metal_c );
3756 }
3757 if( bw != 2 ) {
3758 ter_set( point( 11, 23 ), t_door_metal_c );
3759 ter_set( point( 12, 23 ), t_door_metal_c );
3760 }
3761 }
3762
3763 maybe_insert_stairs( dat.above(), t_stairs_up );
3764 maybe_insert_stairs( terrain_type, t_stairs_down );
3765 } else { // then no json maps for lab_4side were found
3766 switch( rng( 1, 3 ) ) {
3767 case 1:
3768 // Cross shaped
3769 for( int i = 0; i < SEEX * 2; i++ ) {
3770 for( int j = 0; j < SEEY * 2; j++ ) {
3771 if( ( i < lw || i > EAST_EDGE - rw ) ||
3772 ( ( j < SEEY - 1 || j > SEEY ) &&
3773 ( i == SEEX - 2 || i == SEEX + 1 ) ) ) {
3774 ter_set( point( i, j ), t_concrete_wall );
3775 } else if( ( j < tw || j > SOUTH_EDGE - bw ) ||
3776 ( ( i < SEEX - 1 || i > SEEX ) &&
3777 ( j == SEEY - 2 || j == SEEY + 1 ) ) ) {
3778 ter_set( point( i, j ), t_concrete_wall );
3779 } else {
3780 ter_set( point( i, j ), t_thconc_floor );
3781 }
3782 }
3783 }
3784 if( is_ot_match( "stairs", dat.above(), ot_match_type::contains ) ) {
3785 ter_set( point( rng( SEEX - 1, SEEX ), rng( SEEY - 1, SEEY ) ),
3786 t_stairs_up );
3787 }
3788 // Top left
3789 if( one_in( 2 ) ) {
3790 ter_set( point( SEEX - 2, int( SEEY / 2 ) ), t_door_glass_frosted_c );
3791 science_room( this, point( lw, tw ), point( SEEX - 3, SEEY - 3 ), dat.zlevel(), 1 );
3792 } else {
3794 science_room( this, point( lw, tw ), point( SEEX - 3, SEEY - 3 ), dat.zlevel(), 2 );
3795 }
3796 // Top right
3797 if( one_in( 2 ) ) {
3798 ter_set( point( SEEX + 1, int( SEEY / 2 ) ), t_door_glass_frosted_c );
3799 science_room( this, point( SEEX + 2, tw ), point( EAST_EDGE - rw, SEEY - 3 ),
3800 dat.zlevel(), 3 );
3801 } else {
3802 ter_set( point( SEEX + int( SEEX / 2 ), SEEY - 2 ), t_door_glass_frosted_c );
3803 science_room( this, point( SEEX + 2, tw ), point( EAST_EDGE - rw, SEEY - 3 ),
3804 dat.zlevel(), 2 );
3805 }
3806 // Bottom left
3807 if( one_in( 2 ) ) {
3809 science_room( this, point( lw, SEEY + 2 ), point( SEEX - 3, SOUTH_EDGE - bw ),
3810 dat.zlevel(), 0 );
3811 } else {
3812 ter_set( point( SEEX - 2, SEEY + int( SEEY / 2 ) ), t_door_glass_frosted_c );
3813 science_room( this, point( lw, SEEY + 2 ), point( SEEX - 3, SOUTH_EDGE - bw ),
3814 dat.zlevel(), 1 );
3815 }
3816 // Bottom right
3817 if( one_in( 2 ) ) {
3818 ter_set( point( SEEX + int( SEEX / 2 ), SEEY + 1 ), t_door_glass_frosted_c );
3819 science_room( this, point( SEEX + 2, SEEY + 2 ), point( EAST_EDGE - rw, SOUTH_EDGE - bw ),
3820 dat.zlevel(), 0 );
3821 } else {
3822 ter_set( point( SEEX + 1, SEEY + int( SEEY / 2 ) ), t_door_glass_frosted_c );
3823 science_room( this, point( SEEX + 2, SEEY + 2 ), point( EAST_EDGE - rw, SOUTH_EDGE - bw ),
3824 dat.zlevel(), 3 );
3825 }
3826 if( rw == 1 ) {
3829 }
3830 if( bw == 1 ) {
3833 }
3834 if( is_ot_match( "stairs", terrain_type, ot_match_type::contains ) ) { // Stairs going down
3835 std::vector<point> stair_points;
3836 if( tw != 0 ) {
3837 stair_points.push_back( point( SEEX - 1, 2 ) );
3838 stair_points.push_back( point( SEEX - 1, 2 ) );
3839 stair_points.push_back( point( SEEX, 2 ) );
3840 stair_points.push_back( point( SEEX, 2 ) );
3841 }
3842 if( rw != 1 ) {
3843 stair_points.push_back( point( SEEX * 2 - 3, SEEY - 1 ) );
3844 stair_points.push_back( point( SEEX * 2 - 3, SEEY - 1 ) );
3845 stair_points.push_back( point( SEEX * 2 - 3, SEEY ) );
3846 stair_points.push_back( point( SEEX * 2 - 3, SEEY ) );
3847 }
3848 if( bw != 1 ) {
3849 stair_points.push_back( point( SEEX - 1, SEEY * 2 - 3 ) );
3850 stair_points.push_back( point( SEEX - 1, SEEY * 2 - 3 ) );
3851 stair_points.push_back( point( SEEX, SEEY * 2 - 3 ) );
3852 stair_points.push_back( point( SEEX, SEEY * 2 - 3 ) );
3853 }
3854 if( lw != 0 ) {
3855 stair_points.push_back( point( 2, SEEY - 1 ) );
3856 stair_points.push_back( point( 2, SEEY - 1 ) );
3857 stair_points.push_back( point( 2, SEEY ) );
3858 stair_points.push_back( point( 2, SEEY ) );
3859 }
3860 stair_points.push_back( point( int( SEEX / 2 ), SEEY ) );
3861 stair_points.push_back( point( int( SEEX / 2 ), SEEY - 1 ) );
3862 stair_points.push_back( point( int( SEEX / 2 ) + SEEX, SEEY ) );
3863 stair_points.push_back( point( int( SEEX / 2 ) + SEEX, SEEY - 1 ) );
3864 stair_points.push_back( point( SEEX, int( SEEY / 2 ) ) );
3865 stair_points.push_back( point( SEEX + 2, int( SEEY / 2 ) ) );
3866 stair_points.push_back( point( SEEX, int( SEEY / 2 ) + SEEY ) );
3867 stair_points.push_back( point( SEEX + 2, int( SEEY / 2 ) + SEEY ) );
3868 const point p = random_entry( stair_points );
3869 ter_set( p, t_stairs_down );
3870 }
3871
3872 break;
3873
3874 case 2:
3875 // tic-tac-toe # layout
3876 for( int i = 0; i < SEEX * 2; i++ ) {
3877 for( int j = 0; j < SEEY * 2; j++ ) {
3878 if( i < lw || i > EAST_EDGE - rw || i == SEEX - 4 ||
3879 i == SEEX + 3 ) {
3880 ter_set( point( i, j ), t_concrete_wall );
3881 } else if( j < tw || j > SOUTH_EDGE - bw || j == SEEY - 4 ||
3882 j == SEEY + 3 ) {
3883 ter_set( point( i, j ), t_concrete_wall );
3884 } else {
3885 ter_set( point( i, j ), t_thconc_floor );
3886 }
3887 }
3888 }
3889 if( is_ot_match( "stairs", dat.above(), ot_match_type::contains ) ) {
3890 ter_set( point( SEEX - 1, SEEY - 1 ), t_stairs_up );
3891 ter_set( point( SEEX, SEEY - 1 ), t_stairs_up );
3892 ter_set( point( SEEX - 1, SEEY ), t_stairs_up );
3894 }
3895 ter_set( point( SEEX - rng( 0, 1 ), SEEY - 4 ), t_door_glass_frosted_c );
3896 ter_set( point( SEEX - rng( 0, 1 ), SEEY + 3 ), t_door_glass_frosted_c );
3897 ter_set( point( SEEX - 4, SEEY + rng( 0, 1 ) ), t_door_glass_frosted_c );
3898 ter_set( point( SEEX + 3, SEEY + rng( 0, 1 ) ), t_door_glass_frosted_c );
3899 ter_set( point( SEEX - 4, int( SEEY / 2 ) ), t_door_glass_frosted_c );
3900 ter_set( point( SEEX + 3, int( SEEY / 2 ) ), t_door_glass_frosted_c );
3903 ter_set( point( SEEX + int( SEEX / 2 ), SEEY - 4 ), t_door_glass_frosted_c );
3904 ter_set( point( SEEX + int( SEEX / 2 ), SEEY + 3 ), t_door_glass_frosted_c );
3905 ter_set( point( SEEX - 4, SEEY + int( SEEY / 2 ) ), t_door_glass_frosted_c );
3906 ter_set( point( SEEX + 3, SEEY + int( SEEY / 2 ) ), t_door_glass_frosted_c );
3907 science_room( this, point( lw, tw ), point( SEEX - 5, SEEY - 5 ), dat.zlevel(),
3908 rng( 1, 2 ) );
3909 science_room( this, point( SEEX - 3, tw ), point( SEEX + 2, SEEY - 5 ), dat.zlevel(), 2 );
3910 science_room( this, point( SEEX + 4, tw ), point( EAST_EDGE - rw, SEEY - 5 ),
3911 dat.zlevel(), rng( 2, 3 ) );
3912 science_room( this, point( lw, SEEY - 3 ), point( SEEX - 5, SEEY + 2 ), dat.zlevel(), 1 );
3913 science_room( this, point( SEEX + 4, SEEY - 3 ), point( EAST_EDGE - rw, SEEY + 2 ),
3914 dat.zlevel(), 3 );
3915 science_room( this, point( lw, SEEY + 4 ), point( SEEX - 5, SOUTH_EDGE - bw ),
3916 dat.zlevel(), rng( 0, 1 ) );
3917 science_room( this, point( SEEX - 3, SEEY + 4 ), point( SEEX + 2, SOUTH_EDGE - bw ),
3918 dat.zlevel(), 0 );
3919 science_room( this, point( SEEX + 4, SEEX + 4 ), point( EAST_EDGE - rw, SOUTH_EDGE - bw ),
3920 dat.zlevel(), 3 * rng( 0, 1 ) );
3921 if( rw == 1 ) {
3924 }
3925 if( bw == 1 ) {
3928 }
3929 if( is_ot_match( "stairs", terrain_type, ot_match_type::contains ) ) {
3930 ter_set( point( SEEX - 3 + 5 * rng( 0, 1 ), SEEY - 3 + 5 * rng( 0, 1 ) ),
3931 t_stairs_down );
3932 }
3933 break;
3934
3935 case 3:
3936 // Big room
3937 for( int i = 0; i < SEEX * 2; i++ ) {
3938 for( int j = 0; j < SEEY * 2; j++ ) {
3939 if( i < lw || i >= EAST_EDGE - rw ) {
3940 ter_set( point( i, j ), t_concrete_wall );
3941 } else if( j < tw || j >= SOUTH_EDGE - bw ) {
3942 ter_set( point( i, j ), t_concrete_wall );
3943 } else {
3944 ter_set( point( i, j ), t_thconc_floor );
3945 }
3946 }
3947 }
3948 science_room( this, point( lw, tw ), point( EAST_EDGE - rw, SOUTH_EDGE - bw ),
3949 dat.zlevel(), rng( 0, 3 ) );
3950
3951 if( rw == 1 ) {
3954 }
3955 if( bw == 1 ) {
3958 }
3959 maybe_insert_stairs( dat.above(), t_stairs_up );
3960 maybe_insert_stairs( terrain_type, t_stairs_down );
3961 break;
3962 }
3963 } // endif use_hardcoded_4side_map
3964 } // end 1 vs 4 sides
3965 } // end aboveground vs belowground
3966
3967 // Ants will totally wreck up the place
3968 if( is_ot_match( "ants", terrain_type, ot_match_type::contains ) ) {
3969 for( int i = 0; i < SEEX * 2; i++ ) {
3970 for( int j = 0; j < SEEY * 2; j++ ) {
3971 // Carve out a diamond area that covers 2 spaces on each edge.
3972 if( i + j > 10 && i + j < 36 && std::abs( i - j ) < 13 ) {
3973 // Doors and walls get sometimes destroyed:
3974 // 100% at the edge, usually in a central cross, occasionally elsewhere.
3975 if( ( has_flag_ter( "DOOR", point( i, j ) ) || has_flag_ter( "WALL", point( i, j ) ) ) ) {
3976 if( ( i == 0 || j == 0 || i == 23 || j == 23 ) ||
3977 ( !one_in( 3 ) && ( i == 11 || i == 12 || j == 11 || j == 12 ) ) ||
3978 one_in( 4 ) ) {
3979 // bash and usually remove the rubble.
3980 make_rubble( { i, j, abs_sub.z } );
3981 ter_set( point( i, j ), t_rock_floor );
3982 if( !one_in( 3 ) ) {
3983 furn_set( point( i, j ), f_null );
3984 }
3985 }
3986 // and then randomly destroy 5% of the remaining nonstairs.
3987 } else if( one_in( 20 ) &&
3988 !has_flag_ter( "GOES_DOWN", p2 ) &&
3989 !has_flag_ter( "GOES_UP", p2 ) ) {
3990 destroy( { i, j, abs_sub.z } );
3991 // bashed squares can create dirt & floors, but we want rock floors.
3992 if( t_dirt == ter( point( i, j ) ) || t_floor == ter( point( i, j ) ) ) {
3993 ter_set( point( i, j ), t_rock_floor );
3994 }
3995 }
3996 }
3997 }
3998 }
3999 }
4000
4001 // Slimes pretty much wreck up the place, too, but only underground
4002 tw = ( dat.north() == "slimepit" ? SEEY : 0 );
4003 rw = ( dat.east() == "slimepit" ? SEEX + 1 : 0 );
4004 bw = ( dat.south() == "slimepit" ? SEEY + 1 : 0 );
4005 lw = ( dat.west() == "slimepit" ? SEEX : 0 );
4006 if( tw != 0 || rw != 0 || bw != 0 || lw != 0 ) {
4007 for( int i = 0; i < SEEX * 2; i++ ) {
4008 for( int j = 0; j < SEEY * 2; j++ ) {
4009 if( ( ( j <= tw || i >= rw ) && i >= j && ( EAST_EDGE - i ) <= j ) ||
4010 ( ( j >= bw || i <= lw ) && i <= j && ( SOUTH_EDGE - j ) <= i ) ) {
4011 if( one_in( 5 ) ) {
4012 make_rubble( tripoint( i, j, abs_sub.z ), f_rubble_rock, true,
4013 t_slime );
4014 } else if( !one_in( 5 ) ) {
4015 ter_set( point( i, j ), t_slime );
4016 }
4017 }
4018 }
4019 }
4020 }
4021
4022 int light_odds = 0;
4023 // central labs are always fully lit, other labs have half chance of some lights.
4024 if( central_lab ) {
4025 light_odds = 1;
4026 } else if( one_in( 2 ) ) {
4027 // Create a spread of densities, from all possible lights on, to 1/3, ...
4028 // to ~1 per segment.
4029 light_odds = std::pow( rng( 1, 12 ), 1.6 );
4030 }
4031 if( light_odds > 0 ) {
4032 for( int i = 0; i < SEEX * 2; i++ ) {
4033 for( int j = 0; j < SEEY * 2; j++ ) {
4034 if( !( ( i * j ) % 2 || ( i + j ) % 4 ) && one_in( light_odds ) ) {
4035 if( t_thconc_floor == ter( point( i, j ) ) || t_strconc_floor == ter( point( i, j ) ) ) {
4037 }
4038 }
4039 }
4040 }
4041 }
4042
4043 if( tower_lab ) {
4045 }
4046
4047 // Lab special effects.
4048 if( one_in( 10 ) ) {
4049 switch( rng( 1, 7 ) ) {
4050 // full flooding/sewage
4051 case 1: {
4052 if( is_ot_match( "stairs", terrain_type, ot_match_type::contains ) ||
4053 is_ot_match( "ice", terrain_type, ot_match_type::contains ) ) {
4054 // don't flood if stairs because the floor below will not be flooded.
4055 // don't flood if ice lab because there's no mechanic for freezing
4056 // liquid floors.
4057 break;
4058 }
4059 auto fluid_type = one_in( 3 ) ? t_sewage : t_water_sh;
4060 for( int i = 0; i < EAST_EDGE; i++ ) {
4061 for( int j = 0; j < SOUTH_EDGE; j++ ) {
4062 // We spare some terrain to make it look better visually.
4063 if( !one_in( 10 ) && ( t_thconc_floor == ter( point( i, j ) ) ||
4064 t_strconc_floor == ter( point( i, j ) ) ||
4065 t_thconc_floor_olight == ter( point( i, j ) ) ) ) {
4066 ter_set( point( i, j ), fluid_type );
4067 } else if( has_flag_ter( "DOOR", point( i, j ) ) && !one_in( 3 ) ) {
4068 // We want the actual debris, but not the rubble marker or dirt.
4069 make_rubble( { i, j, abs_sub.z } );
4070 ter_set( point( i, j ), fluid_type );
4071 furn_set( point( i, j ), f_null );
4072 }
4073 }
4074 }
4075 break;
4076 }
4077 // minor flooding/sewage
4078 case 2: {
4079 if( is_ot_match( "stairs", terrain_type, ot_match_type::contains ) ||
4080 is_ot_match( "ice", terrain_type, ot_match_type::contains ) ) {
4081 // don't flood if stairs because the floor below will not be flooded.
4082 // don't flood if ice lab because there's no mechanic for freezing
4083 // liquid floors.
4084 break;
4085 }
4086 auto fluid_type = one_in( 3 ) ? t_sewage : t_water_sh;
4087 for( int i = 0; i < 2; ++i ) {
4088 draw_rough_circle( [this, fluid_type]( point p ) {
4089 if( t_thconc_floor == ter( p ) || t_strconc_floor == ter( p ) ||
4090 t_thconc_floor_olight == ter( p ) ) {
4091 ter_set( p, fluid_type );
4092 } else if( has_flag_ter( "DOOR", p ) ) {
4093 // We want the actual debris, but not the rubble marker or dirt.
4094 make_rubble( { p, abs_sub.z } );
4095 ter_set( p, fluid_type );
4096 furn_set( p, f_null );
4097 }
4098 }, point( rng( 1, SEEX * 2 - 2 ), rng( 1, SEEY * 2 - 2 ) ), rng( 3, 6 ) );
4099 }
4100 break;
4101 }
4102 // toxic gas leaks and smoke-filled rooms.
4103 case 3:
4104 case 4: {
4105 bool is_toxic = one_in( 3 );
4106 for( int i = 0; i < SEEX * 2; i++ ) {
4107 for( int j = 0; j < SEEY * 2; j++ ) {
4108 if( one_in( 200 ) && ( t_thconc_floor == ter( point( i, j ) ) ||
4109 t_strconc_floor == ter( point( i, j ) ) ) ) {
4110 if( is_toxic ) {
4111 add_field( {i, j, abs_sub.z}, fd_gas_vent, 1 );
4112 } else {
4113 add_field( {i, j, abs_sub.z}, fd_smoke_vent, 2 );
4114 }
4115 }
4116 }
4117 }
4118 break;
4119 }
4120 // portal with an artifact effect.
4121 case 5: {
4122 tripoint center( rng( 6, SEEX * 2 - 7 ), rng( 6, SEEY * 2 - 7 ), abs_sub.z );
4123 std::vector<artifact_natural_property> valid_props = {
4130 };
4131 draw_rough_circle( [this]( point p ) {
4132 if( has_flag_ter( "GOES_DOWN", p ) ||
4133 has_flag_ter( "GOES_UP", p ) ||
4134 has_flag_ter( "CONSOLE", p ) ) {
4135 return; // spare stairs and consoles.
4136 }
4137 make_rubble( {p, abs_sub.z } );
4138 ter_set( p, t_thconc_floor );
4139 }, center.xy(), 4 );
4140 furn_set( center.xy(), f_null );
4142 create_anomaly( center, random_entry( valid_props ), false );
4143 break;
4144 }
4145 // radioactive accident.
4146 case 6: {
4147 tripoint center( rng( 6, SEEX * 2 - 7 ), rng( 6, SEEY * 2 - 7 ), abs_sub.z );
4148 if( has_flag_ter( "WALL", center.xy() ) ) {
4149 // just skip it, we don't want to risk embedding radiation out of sight.
4150 break;
4151 }
4152 draw_rough_circle( [this]( point p ) {
4153 set_radiation( p, 10 );
4154 }, center.xy(), rng( 7, 12 ) );
4155 draw_circle( [this]( point p ) {
4156 set_radiation( p, 20 );
4157 }, center.xy(), rng( 5, 8 ) );
4158 draw_circle( [this]( point p ) {
4159 set_radiation( p, 30 );
4160 }, center.xy(), rng( 2, 4 ) );
4161 draw_circle( [this]( point p ) {
4162 set_radiation( p, 50 );
4163 }, center.xy(), 1 );
4164 draw_circle( [this]( point p ) {
4165 if( has_flag_ter( "GOES_DOWN", p ) ||
4166 has_flag_ter( "GOES_UP", p ) ||
4167 has_flag_ter( "CONSOLE", p ) ) {
4168 return; // spare stairs and consoles.
4169 }
4170 make_rubble( {p, abs_sub.z } );
4171 ter_set( p, t_thconc_floor );
4172 }, center.xy(), 1 );
4173
4175 center.xy() + point_west, 1, true );
4177 center.xy() + point_west, 1, true );
4178
4179 // damaged mininuke/plut thrown past edge of rubble so the player can see it.
4180 int marker_x = center.x - 2 + 4 * rng( 0, 1 );
4181 int marker_y = center.y + rng( -2, 2 );
4182 if( one_in( 4 ) ) {
4183 spawn_item(
4184 point( marker_x, marker_y ), "mininuke", 1, 1, calendar::start_of_cataclysm, rng( 2, 4 )
4185 );
4186 } else {
4187 item newliquid( "plut_slurry_dense", calendar::start_of_cataclysm );
4188 newliquid.charges = 1;
4189 add_item_or_charges( tripoint( marker_x, marker_y, get_abs_sub().z ),
4190 newliquid );
4191 }
4192 break;
4193 }
4194 // portal with fungal invasion
4195 case 7: {
4196 for( int i = 0; i < EAST_EDGE; i++ ) {
4197 for( int j = 0; j < SOUTH_EDGE; j++ ) {
4198 // Create a mostly spread fungal area throughout entire lab.
4199 if( !one_in( 5 ) && ( has_flag( "FLAT", point( i, j ) ) ) ) {
4200 ter_set( point( i, j ), t_fungus_floor_in );
4201 if( has_flag_furn( "ORGANIC", point( i, j ) ) ) {
4202 furn_set( point( i, j ), f_fungal_clump );
4203 }
4204 } else if( has_flag_ter( "DOOR", point( i, j ) ) && !one_in( 5 ) ) {
4205 ter_set( point( i, j ), t_fungus_floor_in );
4206 } else if( has_flag_ter( "WALL", point( i, j ) ) && one_in( 3 ) ) {
4207 ter_set( point( i, j ), t_fungus_wall );
4208 }
4209 }
4210 }
4211 tripoint center( rng( 6, SEEX * 2 - 7 ), rng( 6, SEEY * 2 - 7 ), abs_sub.z );
4212
4213 // Make a portal surrounded by more dense fungal stuff and a fungaloid.
4214 draw_rough_circle( [this]( point p ) {
4215 if( has_flag_ter( "GOES_DOWN", p ) ||
4216 has_flag_ter( "GOES_UP", p ) ||
4217 has_flag_ter( "CONSOLE", p ) ) {
4218 return; // spare stairs and consoles.
4219 }
4220 if( has_flag_ter( "WALL", p ) ) {
4221 ter_set( p, t_fungus_wall );
4222 } else {
4224 if( one_in( 3 ) ) {
4226 } else if( one_in( 10 ) ) {
4227 ter_set( p, t_marloss );
4228 }
4229 }
4230 }, center.xy(), 3 );
4232 furn_set( center.xy(), f_null );
4234 place_spawns( GROUP_FUNGI_FUNGALOID, 1, center.xy() + point( -2, -2 ),
4235 center.xy() + point( 2, 2 ), 1, true );
4236
4237 break;
4238 }
4239 }
4240 }
4241 } else if( terrain_type == "lab_finale" || terrain_type == "ice_lab_finale" ||
4242 terrain_type == "central_lab_finale" || terrain_type == "tower_lab_finale" ) {
4243
4244 ice_lab = is_ot_match( "ice_lab", terrain_type, ot_match_type::prefix );
4245 central_lab = is_ot_match( "central_lab", terrain_type, ot_match_type::prefix );
4246 tower_lab = is_ot_match( "tower_lab", terrain_type, ot_match_type::prefix );
4247
4248 if( ice_lab ) {
4249 int temperature = -20 + 30 * dat.zlevel();
4251 set_temperature( p2 + point( SEEX, 0 ), temperature );
4252 set_temperature( p2 + point( 0, SEEY ), temperature );
4254 }
4255
4256 tw = is_ot_match( "lab", dat.north(), ot_match_type::contains ) ? 0 : 2;
4257 rw = is_ot_match( "lab", dat.east(), ot_match_type::contains ) ? 1 : 2;
4258 bw = is_ot_match( "lab", dat.south(), ot_match_type::contains ) ? 1 : 2;
4259 lw = is_ot_match( "lab", dat.west(), ot_match_type::contains ) ? 0 : 2;
4260
4261 const int hardcoded_finale_map_weight = 500; // weight of all hardcoded maps.
4262 // If you remove the usage of "lab_finale_1level" here, remove it from mapgen_factory::get_usages above as well.
4263 if( oter_mapgen.generate( dat, "lab_finale_1level", hardcoded_finale_map_weight ) ) {
4264 // If the map template hasn't handled borders, handle them in code.
4265 // Rotated maps cannot handle borders and have to be caught in code.
4266 // We determine if a border isn't handled by checking the east-facing
4267 // border space where the door normally is -- it should be a wall or door.
4268 tripoint east_border( 23, 11, abs_sub.z );
4269 if( !has_flag_ter( "WALL", east_border ) && !has_flag_ter( "DOOR", east_border ) ) {
4270 // TODO: create a ter_reset function that does ter_set, furn_set, and i_clear?
4271 ter_id lw_type = tower_lab ? t_reinforced_glass : t_concrete_wall;
4272 ter_id tw_type = tower_lab ? t_reinforced_glass : t_concrete_wall;
4273 ter_id rw_type = tower_lab && rw == 2 ? t_reinforced_glass : t_concrete_wall;
4274 ter_id bw_type = tower_lab && bw == 2 ? t_reinforced_glass : t_concrete_wall;
4275 for( int i = 0; i < SEEX * 2; i++ ) {
4276 ter_set( point( 23, i ), rw_type );
4277 furn_set( point( 23, i ), f_null );
4278 i_clear( tripoint( 23, i, get_abs_sub().z ) );
4279
4280 ter_set( point( i, 23 ), bw_type );
4281 furn_set( point( i, 23 ), f_null );
4282 i_clear( tripoint( i, 23, get_abs_sub().z ) );
4283
4284 if( lw == 2 ) {
4285 ter_set( point( 0, i ), lw_type );
4286 furn_set( point( 0, i ), f_null );
4287 i_clear( tripoint( 0, i, get_abs_sub().z ) );
4288 }
4289 if( tw == 2 ) {
4290 ter_set( point( i, 0 ), tw_type );
4291 furn_set( point( i, 0 ), f_null );
4292 i_clear( tripoint( i, 0, get_abs_sub().z ) );
4293 }
4294 }
4295 if( rw != 2 ) {
4296 ter_set( point( 23, 11 ), t_door_metal_c );
4297 ter_set( point( 23, 12 ), t_door_metal_c );
4298 }
4299 if( bw != 2 ) {
4300 ter_set( point( 11, 23 ), t_door_metal_c );
4301 ter_set( point( 12, 23 ), t_door_metal_c );
4302 }
4303 }
4304 } else { // then no json maps for lab_finale_1level were found
4305 // Start by setting up a large, empty room.
4306 for( int i = 0; i < SEEX * 2; i++ ) {
4307 for( int j = 0; j < SEEY * 2; j++ ) {
4308 if( i < lw || i > EAST_EDGE - rw ) {
4309 ter_set( point( i, j ), t_concrete_wall );
4310 } else if( j < tw || j > SOUTH_EDGE - bw ) {
4311 ter_set( point( i, j ), t_concrete_wall );
4312 } else {
4313 ter_set( point( i, j ), t_thconc_floor );
4314 }
4315 }
4316 }
4317 if( rw == 1 ) {
4320 }
4321 if( bw == 1 ) {
4324 }
4325
4326 int loot_variant; //only used for weapons testing variant.
4327 computer *tmpcomp = nullptr;
4328 switch( rng( 1, 5 ) ) {
4329 // Weapons testing - twice as common because it has 4 variants.
4330 case 1:
4331 case 2:
4332 loot_variant = rng( 1, 100 ); //The variants have a 67/22/7/4 split.
4333 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, 6 ), point( 6, 6 ), 1, true );
4334 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, 6 ),
4335 point( SEEX * 2 - 7, 6 ), 1, true );
4336 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, SEEY * 2 - 7 ),
4337 point( 6, SEEY * 2 - 7 ), 1, true );
4338 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, SEEY * 2 - 7 ),
4339 point( SEEX * 2 - 7, SEEY * 2 - 7 ), 1, true );
4340 spawn_item( point( SEEX - 4, SEEY - 2 ), "id_science" );
4341 if( loot_variant <= 96 ) {
4342 mtrap_set( this, point( SEEX - 3, SEEY - 3 ), tr_dissector );
4343 mtrap_set( this, point( SEEX + 2, SEEY - 3 ), tr_dissector );
4344 mtrap_set( this, point( SEEX - 3, SEEY + 2 ), tr_dissector );
4345 mtrap_set( this, point( SEEX + 2, SEEY + 2 ), tr_dissector );
4346 line( this, t_reinforced_glass, point( SEEX + 1, SEEY + 1 ), point( SEEX - 2, SEEY + 1 ) );
4347 line( this, t_reinforced_glass, point( SEEX - 2, SEEY ), point( SEEX - 2, SEEY - 2 ) );
4348 line( this, t_reinforced_glass, point( SEEX - 1, SEEY - 2 ), point( SEEX + 1, SEEY - 2 ) );
4349 ter_set( point( SEEX + 1, SEEY - 1 ), t_reinforced_glass );
4351 furn_set( point( SEEX - 1, SEEY - 1 ), f_table );
4352 furn_set( point( SEEX, SEEY - 1 ), f_table );
4353 furn_set( point( SEEX - 1, SEEY ), f_table );
4354 furn_set( point( SEEX, SEEY ), f_table );
4355 if( loot_variant <= 67 ) {
4356 spawn_item( point( SEEX, SEEY - 1 ), "UPS_off" );
4357 spawn_item( point( SEEX, SEEY - 1 ), "heavy_battery_cell" );
4358 spawn_item( point( SEEX - 1, SEEY ), "v29" );
4359 spawn_item( point( SEEX - 1, SEEY ), "laser_rifle", dice( 1, 0 ) );
4360 spawn_item( point( SEEX, SEEY ), "plasma_gun" );
4361 spawn_item( point( SEEX, SEEY ), "plasma" );
4362 spawn_item( point( SEEX - 1, SEEY ), "recipe_atomic_battery" );
4363 spawn_item( point( SEEX + 1, SEEY ), "plut_cell", rng( 8, 20 ) );
4364 } else if( loot_variant < 89 ) {
4365 spawn_item( point( SEEX - 1, SEEY - 1 ), "mininuke", dice( 3, 6 ) );
4366 spawn_item( point( SEEX, SEEY - 1 ), "mininuke", dice( 3, 6 ) );
4367 spawn_item( point( SEEX - 1, SEEY ), "mininuke", dice( 3, 6 ) );
4368 spawn_item( point( SEEX, SEEY ), "mininuke", dice( 3, 6 ) );
4369 spawn_item( point( SEEX, SEEY ), "recipe_atomic_battery" );
4370 spawn_item( point( SEEX + 1, SEEY ), "plut_cell", rng( 8, 20 ) );
4371 } else { // loot_variant between 90 and 96.
4372 spawn_item( point( SEEX - 1, SEEY - 1 ), "rm13_armor" );
4373 spawn_item( point( SEEX, SEEY - 1 ), "plut_cell" );
4374 spawn_item( point( SEEX - 1, SEEY ), "plut_cell" );
4375 spawn_item( point( SEEX, SEEY ), "recipe_caseless" );
4376 }
4377 } else { // 4% of the lab ends will be this weapons testing end.
4378 mtrap_set( this, point( SEEX - 4, SEEY - 3 ), tr_dissector );
4379 mtrap_set( this, point( SEEX + 3, SEEY - 3 ), tr_dissector );
4380 mtrap_set( this, point( SEEX - 4, SEEY + 2 ), tr_dissector );
4381 mtrap_set( this, point( SEEX + 3, SEEY + 2 ), tr_dissector );
4382
4383 furn_set( point( SEEX - 2, SEEY - 1 ), f_rack );
4384 furn_set( point( SEEX - 1, SEEY - 1 ), f_rack );
4385 furn_set( point( SEEX, SEEY - 1 ), f_rack );
4386 furn_set( point( SEEX + 1, SEEY - 1 ), f_rack );
4387 furn_set( point( SEEX - 2, SEEY ), f_rack );
4388 furn_set( point( SEEX - 1, SEEY ), f_rack );
4389 furn_set( point( SEEX, SEEY ), f_rack );
4390 furn_set( point( SEEX + 1, SEEY ), f_rack );
4391 line( this, t_reinforced_door_glass_c, point( SEEX - 2, SEEY - 2 ),
4392 point( SEEX + 1, SEEY - 2 ) );
4393 line( this, t_reinforced_door_glass_c, point( SEEX - 2, SEEY + 1 ),
4394 point( SEEX + 1, SEEY + 1 ) );
4395 line( this, t_reinforced_glass, point( SEEX - 3, SEEY - 2 ), point( SEEX - 3, SEEY + 1 ) );
4396 line( this, t_reinforced_glass, point( SEEX + 2, SEEY - 2 ), point( SEEX + 2, SEEY + 1 ) );
4397 place_items( item_group_id( "ammo_rare" ), 96, point( SEEX - 2, SEEY - 1 ),
4398 point( SEEX + 1, SEEY - 1 ), false, calendar::start_of_cataclysm );
4399 place_items( item_group_id( "guns_rare" ), 96, point( SEEX - 2, SEEY ), point( SEEX + 1, SEEY ),
4400 false,
4402 spawn_item( point( SEEX + 1, SEEY ), "plut_cell", rng( 1, 10 ) );
4403 }
4404 break;
4405 // Netherworld access
4406 case 3: {
4407 bool monsters_end = false;
4408 if( !one_in( 4 ) ) { // Trapped netherworld monsters
4409 monsters_end = true;
4410 tw = rng( SEEY + 3, SEEY + 5 );
4411 bw = tw + 4;
4412 lw = rng( SEEX - 6, SEEX - 2 );
4413 rw = lw + 6;
4414 for( int i = lw; i <= rw; i++ ) {
4415 for( int j = tw; j <= bw; j++ ) {
4416 if( j == tw || j == bw ) {
4417 if( ( i - lw ) % 2 == 0 ) {
4418 ter_set( point( i, j ), t_concrete_wall );
4419 } else {
4420 ter_set( point( i, j ), t_reinforced_glass );
4421 }
4422 } else if( ( i - lw ) % 2 == 0 ) {
4423 ter_set( point( i, j ), t_concrete_wall );
4424 } else if( j == tw + 2 ) {
4425 ter_set( point( i, j ), t_concrete_wall );
4426 } else { // Empty space holds monsters!
4427 place_spawns( GROUP_NETHER, 1, point( i, j ), point( i, j ), 1, true );
4428 }
4429 }
4430 }
4431 }
4432
4433 spawn_item( point( SEEX - 1, 8 ), "id_science" );
4434 tmpcomp = add_computer( tripoint( SEEX, 8, abs_sub.z ),
4435 _( "Sub-prime contact console" ), 7 );
4436 if( monsters_end ) { //only add these options when there are monsters.
4437 tmpcomp->add_option( _( "Terminate Specimens" ), COMPACT_TERMINATE, 2 );
4438 tmpcomp->add_option( _( "Release Specimens" ), COMPACT_RELEASE, 3 );
4439 }
4440 tmpcomp->add_option( _( "Toggle Portal" ), COMPACT_PORTAL, 8 );
4441 tmpcomp->add_option( _( "Activate Resonance Cascade" ), COMPACT_CASCADE, 10 );
4442 tmpcomp->add_failure( COMPFAIL_MANHACKS );
4443 tmpcomp->add_failure( COMPFAIL_SECUBOTS );
4444 tmpcomp->set_access_denied_msg(
4445 _( "ERROR! Access denied! Unauthorized access will be met with lethal force!" ) );
4446 ter_set( point( SEEX - 2, 4 ), t_radio_tower );
4447 ter_set( point( SEEX + 1, 4 ), t_radio_tower );
4448 ter_set( point( SEEX - 2, 7 ), t_radio_tower );
4449 ter_set( point( SEEX + 1, 7 ), t_radio_tower );
4450 }
4451 break;
4452
4453 // Bionics
4454 case 4: {
4455 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, 6 ), point( 6, 6 ), 1, true );
4456 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, 6 ),
4457 point( SEEX * 2 - 7, 6 ), 1, true );
4458 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, SEEY * 2 - 7 ),
4459 point( 6, SEEY * 2 - 7 ), 1, true );
4460 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, SEEY * 2 - 7 ),
4461 point( SEEX * 2 - 7, SEEY * 2 - 7 ), 1, true );
4462 mtrap_set( this, point( SEEX - 2, SEEY - 2 ), tr_dissector );
4463 mtrap_set( this, point( SEEX + 1, SEEY - 2 ), tr_dissector );
4464 mtrap_set( this, point( SEEX - 2, SEEY + 1 ), tr_dissector );
4465 mtrap_set( this, point( SEEX + 1, SEEY + 1 ), tr_dissector );
4466 square_furn( this, f_counter, point( SEEX - 1, SEEY - 1 ), point( SEEX, SEEY ) );
4467 int item_count = 0;
4468 while( item_count < 5 ) {
4469 item_count += place_items( item_group_id( "bionics" ), 75, point( SEEX - 1, SEEY - 1 ),
4470 point( SEEX, SEEY ), false, calendar::start_of_cataclysm ).size();
4471 }
4472 line( this, t_reinforced_glass, point( SEEX - 2, SEEY - 2 ), point( SEEX + 1, SEEY - 2 ) );
4473 line( this, t_reinforced_glass, point( SEEX - 2, SEEY + 1 ), point( SEEX + 1, SEEY + 1 ) );
4474 line( this, t_reinforced_glass, point( SEEX - 2, SEEY - 1 ), point( SEEX - 2, SEEY ) );
4475 line( this, t_reinforced_glass, point( SEEX + 1, SEEY - 1 ), point( SEEX + 1, SEEY ) );
4476 spawn_item( point( SEEX - 4, SEEY - 3 ), "id_science" );
4477 ter_set( point( SEEX - 3, SEEY - 3 ), t_console );
4478 tmpcomp = add_computer( tripoint( SEEX - 3, SEEY - 3, abs_sub.z ),
4479 _( "Bionic access" ), 3 );
4480 tmpcomp->add_option( _( "Manifest" ), COMPACT_LIST_BIONICS, 0 );
4481 tmpcomp->add_option( _( "Open Chambers" ), COMPACT_RELEASE, 5 );
4482 tmpcomp->add_failure( COMPFAIL_MANHACKS );
4483 tmpcomp->add_failure( COMPFAIL_SECUBOTS );
4484 tmpcomp->set_access_denied_msg(
4485 _( "ERROR! Access denied! Unauthorized access will be met with lethal force!" ) );
4486 }
4487 break;
4488
4489 // CVD Forge
4490 case 5:
4491 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, 6 ), point( 6, 6 ), 1, true );
4492 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, 6 ),
4493 point( SEEX * 2 - 7, 6 ), 1, true );
4494 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, SEEY * 2 - 7 ),
4495 point( 6, SEEY * 2 - 7 ), 1, true );
4496 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, SEEY * 2 - 7 ),
4497 point( SEEX * 2 - 7, SEEY * 2 - 7 ), 1, true );
4498 line( this, t_cvdbody, point( SEEX - 2, SEEY - 2 ), point( SEEX - 2, SEEY + 1 ) );
4499 line( this, t_cvdbody, point( SEEX - 1, SEEY - 2 ), point( SEEX - 1, SEEY + 1 ) );
4500 line( this, t_cvdbody, point( SEEX, SEEY - 1 ), point( SEEX, SEEY + 1 ) );
4501 line( this, t_cvdbody, point( SEEX + 1, SEEY - 2 ), point( SEEX + 1, SEEY + 1 ) );
4502 ter_set( point( SEEX, SEEY - 2 ), t_cvdmachine );
4503 spawn_item( point( SEEX, SEEY - 3 ), "id_science" );
4504 break;
4505 }
4506 } // end use_hardcoded_lab_finale
4507
4508 // Handle stairs in the unlikely case they are needed.
4509
4510 const auto maybe_insert_stairs = [this]( const oter_id & terrain, const ter_id & t_stair_type ) {
4511 if( is_ot_match( "stairs", terrain, ot_match_type::contains ) ) {
4512 const auto predicate = [this]( const tripoint & p ) {
4513 return ter( p ) == t_thconc_floor && furn( p ) == f_null &&
4514 tr_at( p ).is_null();
4515 };
4516 const auto range = points_in_rectangle( { 0, 0, abs_sub.z },
4517 { SEEX * 2 - 2, SEEY * 2 - 2, abs_sub.z } );
4518 if( const auto p = random_point( range, predicate ) ) {
4519 ter_set( *p, t_stair_type );
4520 }
4521 }
4522 };
4523 maybe_insert_stairs( dat.above(), t_stairs_up );
4524 maybe_insert_stairs( terrain_type, t_stairs_down );
4525
4526 int light_odds = 0;
4527 // central labs are always fully lit, other labs have half chance of some lights.
4528 if( central_lab ) {
4529 light_odds = 1;
4530 } else if( one_in( 2 ) ) {
4531 light_odds = std::pow( rng( 1, 12 ), 1.6 );
4532 }
4533 if( light_odds > 0 ) {
4534 for( int i = 0; i < SEEX * 2; i++ ) {
4535 for( int j = 0; j < SEEY * 2; j++ ) {
4536 if( !( ( i * j ) % 2 || ( i + j ) % 4 ) && one_in( light_odds ) ) {
4537 if( t_thconc_floor == ter( point( i, j ) ) || t_strconc_floor == ter( point( i, j ) ) ) {
4539 }
4540 }
4541 }
4542 }
4543 }
4544 }
4545}
void set_access_denied_msg(const std::string &new_msg)
Definition: computer.cpp:97
void add_failure(const computer_failure &failure)
Definition: computer.cpp:87
void add_option(const computer_option &opt)
Definition: computer.cpp:76
void set_temperature(const tripoint &p, int temperature)
Definition: map.cpp:4139
computer * add_computer(const tripoint &p, const std::string &name, int security)
Definition: mapgen.cpp:5820
void i_clear(const tripoint &p)
Definition: map.cpp:4187
std::vector< item * > place_items(const item_group_id &loc, int chance, const tripoint &p1, const tripoint &p2, bool ongrass, const time_point &turn, int magazine=0, int ammo=0)
Place items from item group in the rectangle f - t.
Definition: mapgen.cpp:5550
void trap_set(const tripoint &p, const trap_id &type)
Definition: map.cpp:5250
bool generate(mapgendata &dat, const std::string &key, const int hardcoded_weight=0) const
Definition: mapgen.cpp:346
int zlevel() const
Definition: mapgendata.h:99
@ COMPACT_RELEASE
Definition: computer.h:42
@ COMPACT_TERMINATE
Definition: computer.h:59
@ COMPACT_PORTAL
Definition: computer.h:40
@ COMPACT_CASCADE
Definition: computer.h:19
@ COMPACT_LIST_BIONICS
Definition: computer.h:32
@ COMPFAIL_SECUBOTS
Definition: computer.h:77
@ COMPFAIL_MANHACKS
Definition: computer.h:74
void draw_rough_circle(std::function< void(point)>set, point p, int rad)
@ prefix
Definition: enums.h:79
@ contains
Definition: enums.h:83
field_type_id fd_gas_vent
Definition: field_type.cpp:350
field_type_id fd_smoke_vent
Definition: field_type.cpp:385
ter_id t_door_glass_frosted_c
Definition: mapdata.cpp:666
ter_id t_cvdmachine
Definition: mapdata.cpp:714
ter_id t_slime
Definition: mapdata.cpp:639
ter_id t_strconc_floor
Definition: mapdata.cpp:633
furn_id f_table
Definition: mapdata.cpp:1106
furn_id f_fungal_clump
Definition: mapdata.cpp:1118
ter_id t_cvdbody
Definition: mapdata.cpp:714
ter_id t_radio_tower
Definition: mapdata.cpp:705
ter_id t_fungus_floor_in
Definition: mapdata.cpp:692
furn_id f_counter
Definition: mapdata.cpp:1107
furn_id f_rack
Definition: mapdata.cpp:1109
ter_id t_fungus_wall
Definition: mapdata.cpp:692
ter_id t_reinforced_glass
Definition: mapdata.cpp:652
ter_id t_concrete_wall
Definition: mapdata.cpp:648
ter_id t_floor
Definition: mapdata.cpp:634
ter_id t_thconc_floor_olight
Definition: mapdata.cpp:633
ter_id t_bars
Definition: mapdata.cpp:655
ter_id t_thconc_floor
Definition: mapdata.cpp:633
furn_id f_rubble_rock
Definition: mapdata.cpp:1099
ter_id t_stairs_up
Definition: mapdata.cpp:720
ter_id t_stairs_down
Definition: mapdata.cpp:720
ter_id t_marloss
Definition: mapdata.cpp:692
ter_id t_door_metal_locked
Definition: mapdata.cpp:664
ter_id t_card_science
Definition: mapdata.cpp:724
ter_id t_reinforced_door_glass_c
Definition: mapdata.cpp:654
furn_id f_flower_fungal
Definition: mapdata.cpp:1118
static const mongroup_id GROUP_ROBOT_SECUBOT("GROUP_ROBOT_SECUBOT")
void square_furn(map *m, const furn_id &type, point p1, point p2)
Definition: mapgen.cpp:6512
static const mongroup_id GROUP_HAZMATBOT("GROUP_HAZMATBOT")
static const mongroup_id GROUP_NETHER("GROUP_NETHER")
static const mongroup_id GROUP_TURRET("GROUP_TURRET")
void line(map *m, const ter_id &type, point p1, point p2)
Definition: mapgen.cpp:6492
const int SOUTH_EDGE
Definition: mapgen.cpp:2955
static void science_room(map *m, point p1, point p2, int z, int rotate)
Definition: mapgen.cpp:5986
const int EAST_EDGE
Definition: mapgen.cpp:2956
static mapgen_factory oter_mapgen
Definition: mapgen.cpp:355
static const mongroup_id GROUP_FUNGI_FUNGALOID("GROUP_FUNGI_FUNGALOID")
static const mongroup_id GROUP_LAB("GROUP_LAB")
static const trap_str_id tr_portal("tr_portal")
static const trap_str_id tr_dissector("tr_dissector")
const time_point & start_of_cataclysm
Definition: calendar.cpp:33
std::pair< item, int > item_count
Definition: pickup.cpp:64
int dice(int number, int sides)
Definition: rng.cpp:85
V random_entry(const C &container, D default_value)
Returns a random entry in the container.
Definition: rng.h:88

References _, mapgendata::above(), abs_sub, add_computer(), computer::add_failure(), add_field(), add_item_or_charges(), computer::add_option(), ARTPROP_BREATHING, ARTPROP_CRACKLING, ARTPROP_GLOWING, ARTPROP_SCALED, ARTPROP_WARM, ARTPROP_WHISPERING, center, item::charges, COMPACT_CASCADE, COMPACT_LIST_BIONICS, COMPACT_PORTAL, COMPACT_RELEASE, COMPACT_TERMINATE, COMPFAIL_MANHACKS, COMPFAIL_SECUBOTS, connects_to(), contains, create_anomaly(), debugmsg, destroy(), dice(), draw_circle(), draw_rough_circle(), mapgendata::east(), EAST_EDGE, f_counter, f_flower_fungal, f_fungal_clump, f_null, f_rack, f_rubble_rock, f_table, fd_gas_vent, fd_smoke_vent, furn(), furn_set(), mapgen_factory::generate(), get_abs_sub(), GROUP_FUNGI_FUNGALOID, GROUP_HAZMATBOT, GROUP_LAB, GROUP_NETHER, GROUP_ROBOT_SECUBOT, GROUP_TURRET, has_flag(), has_flag_furn(), has_flag_ter(), i_clear(), trap::is_null(), is_ot_match(), line(), make_rubble(), mtrap_set(), mapgendata::north(), one_in(), oter_mapgen, place_items(), place_spawns(), point_west, point_zero, points_in_rectangle(), prefix, random_entry(), random_point(), rng(), rotate(), science_room(), SEEX, SEEY, computer::set_access_denied_msg(), set_radiation(), set_temperature(), mapgendata::south(), SOUTH_EDGE, spawn_item(), square_furn(), calendar::start_of_cataclysm, t_bars, t_card_science, t_concrete_wall, t_console, t_cvdbody, t_cvdmachine, t_dirt, t_door_glass_frosted_c, t_door_metal_c, t_door_metal_locked, t_floor, t_fungus_floor_in, t_fungus_wall, t_marloss, t_radio_tower, t_reinforced_door_glass_c, t_reinforced_glass, t_rock_floor, t_sewage, t_slime, t_stairs_down, t_stairs_up, t_strconc_floor, t_thconc_floor, t_thconc_floor_olight, t_water_sh, ter(), ter_set(), terrain, mapgendata::terrain_type(), tr_at(), tr_dissector, tr_portal, trap_set(), type, mapgendata::west(), tripoint::z, and mapgendata::zlevel().

Referenced by draw_map().

◆ draw_line_furn()

void map::draw_line_furn ( const furn_id type,
point  p1,
point  p2 
)

Definition at line 8421 of file map.cpp.

8422{
8423 draw_line( [this, type]( point p ) {
8424 this->furn_set( p, type );
8425 }, p1, p2 );
8426}
void draw_line(std::function< void(point)>set, point p1, point p2)

References draw_line(), furn_set(), and type.

Referenced by jmapgen_setmap::apply(), and line_furn().

◆ draw_line_ter()

void map::draw_line_ter ( const ter_id type,
point  p1,
point  p2 
)

Definition at line 8414 of file map.cpp.

8415{
8416 draw_line( [this, type]( point p ) {
8417 this->ter_set( p, type );
8418 }, p1, p2 );
8419}

References draw_line(), ter_set(), and type.

Referenced by jmapgen_setmap::apply(), and line().

◆ draw_map()

void map::draw_map ( mapgendata dat)
protected

Definition at line 2915 of file mapgen.cpp.

2916{
2917 const oter_id &terrain_type = dat.terrain_type();
2918 const std::string function_key = terrain_type->get_mapgen_id();
2919 bool found = true;
2920
2921 const bool generated = run_mapgen_func( function_key, dat );
2922
2923 if( !generated ) {
2924 if( is_ot_match( "slimepit", terrain_type, ot_match_type::prefix ) ||
2925 is_ot_match( "slime_pit", terrain_type, ot_match_type::prefix ) ) {
2926 draw_slimepit( dat );
2927 } else if( is_ot_match( "triffid", terrain_type, ot_match_type::prefix ) ) {
2928 draw_triffid( dat );
2929 } else if( is_ot_match( "office", terrain_type, ot_match_type::prefix ) ) {
2930 draw_office_tower( dat );
2931 } else if( is_ot_match( "temple", terrain_type, ot_match_type::prefix ) ) {
2932 draw_temple( dat );
2933 } else if( is_ot_match( "mine", terrain_type, ot_match_type::prefix ) ) {
2934 draw_mine( dat );
2935 } else if( is_ot_match( "anthill", terrain_type, ot_match_type::contains ) ) {
2936 draw_anthill( dat );
2937 } else if( is_ot_match( "lab", terrain_type, ot_match_type::contains ) ) {
2938 draw_lab( dat );
2939 } else {
2940 found = false;
2941 }
2942 }
2943
2944 if( !found ) {
2945 // not one of the hardcoded ones!
2946 // load from JSON???
2947 debugmsg( "Error: tried to generate map for omtype %s, \"%s\" (id_mapgen %s)",
2948 terrain_type.id().c_str(), terrain_type->get_name(), function_key.c_str() );
2949 fill_background( this, t_floor );
2950 }
2951
2952 draw_connections( dat );
2953}
void draw_office_tower(mapgendata &dat)
Definition: mapgen.cpp:2958
void draw_mine(mapgendata &dat)
Definition: mapgen.cpp:4793
void draw_triffid(mapgendata &dat)
Definition: mapgen.cpp:5125
void draw_anthill(mapgendata &dat)
Definition: mapgen.cpp:5063
void draw_slimepit(mapgendata &dat)
Definition: mapgen.cpp:5081
void draw_lab(mapgendata &dat)
Definition: mapgen.cpp:3546
void draw_connections(mapgendata &dat)
Definition: mapgen.cpp:5273
void draw_temple(mapgendata &dat)
Definition: mapgen.cpp:4547
void fill_background(map *m, const ter_id &type)
Definition: mapgen.cpp:6500
bool run_mapgen_func(const std::string &mapgen_id, mapgendata &dat)
Definition: mapgen.cpp:6724
std::string get_name() const
Definition: omdata.h:205
std::string get_mapgen_id() const
Definition: overmap.cpp:798

References string_id< T >::c_str(), contains, debugmsg, draw_anthill(), draw_connections(), draw_lab(), draw_mine(), draw_office_tower(), draw_slimepit(), draw_temple(), draw_triffid(), fill_background(), oter_t::get_mapgen_id(), oter_t::get_name(), int_id< T >::id(), is_ot_match(), prefix, run_mapgen_func(), t_floor, and mapgendata::terrain_type().

Referenced by generate().

◆ draw_maptile()

bool map::draw_maptile ( const catacurses::window w,
const tripoint p,
const maptile tile,
const drawsq_params params 
) const
private

Internal version of the drawsq.

Keeps a cached maptile for less re-getting. Returns false if it has drawn all it should, true if draw_from_above should be called after.

Definition at line 5938 of file map.cpp.

5940{
5941 drawsq_params param = params;
5942 nc_color tercol;
5943 const ter_t &curr_ter = curr_maptile.get_ter_t();
5944 const furn_t &curr_furn = curr_maptile.get_furn_t();
5945 const trap &curr_trap = curr_maptile.get_trap().obj();
5946 const field &curr_field = curr_maptile.get_field();
5947 int sym;
5948 bool hi = false;
5949 bool graf = false;
5950 bool draw_item_sym = false;
5951
5952 int terrain_sym;
5953 if( curr_ter.has_flag( TFLAG_AUTO_WALL_SYMBOL ) ) {
5954 terrain_sym = determine_wall_corner( p );
5955 } else {
5956 terrain_sym = curr_ter.symbol();
5957 }
5958
5959 if( curr_furn.id ) {
5960 sym = curr_furn.symbol();
5961 tercol = curr_furn.color();
5962 } else {
5963 sym = terrain_sym;
5964 tercol = curr_ter.color();
5965 }
5966 if( curr_ter.has_flag( TFLAG_SWIMMABLE ) && curr_ter.has_flag( TFLAG_DEEP_WATER ) &&
5967 !g->u.is_underwater() ) {
5968 param.show_items( false ); // Can only see underwater items if WE are underwater
5969 }
5970 // If there's a trap here, and we have sufficient perception, draw that instead
5971 if( curr_trap.can_see( p, g->u ) ) {
5972 tercol = curr_trap.color;
5973 if( curr_trap.sym == '%' ) {
5974 switch( rng( 1, 5 ) ) {
5975 case 1:
5976 sym = '*';
5977 break;
5978 case 2:
5979 sym = '0';
5980 break;
5981 case 3:
5982 sym = '8';
5983 break;
5984 case 4:
5985 sym = '&';
5986 break;
5987 case 5:
5988 sym = '+';
5989 break;
5990 }
5991 } else {
5992 sym = curr_trap.sym;
5993 }
5994 }
5995 if( curr_field.field_count() > 0 ) {
5996 const field_type_id &fid = curr_field.displayed_field_type();
5997 const field_entry *fe = curr_field.find_field( fid );
5998 const auto field_symbol = fid->get_symbol();
5999 if( field_symbol == "&" || fe == nullptr ) {
6000 // Do nothing, a '&' indicates invisible fields.
6001 } else if( field_symbol == "*" ) {
6002 // A random symbol.
6003 switch( rng( 1, 5 ) ) {
6004 case 1:
6005 sym = '*';
6006 break;
6007 case 2:
6008 sym = '0';
6009 break;
6010 case 3:
6011 sym = '8';
6012 break;
6013 case 4:
6014 sym = '&';
6015 break;
6016 case 5:
6017 sym = '+';
6018 break;
6019 }
6020 } else {
6021 // A field symbol '%' indicates the field should not hide
6022 // items/terrain. When the symbol is not '%' it will
6023 // hide items (the color is still inverted if there are items,
6024 // but the tile symbol is not changed).
6025 // draw_item_sym indicates that the item symbol should be used
6026 // even if sym is not '.'.
6027 // As we don't know at this stage if there are any items
6028 // (that are visible to the player!), we always set the symbol.
6029 // If there are items and the field does not hide them,
6030 // the code handling items will override it.
6031 draw_item_sym = ( field_symbol == "'%" );
6032 // If field display_priority is > 1, and the field is set to hide items,
6033 //draw the field as it obscures what's under it.
6034 if( ( field_symbol != "%" && fid.obj().priority > 1 ) || ( field_symbol != "%" &&
6035 sym == '.' ) ) {
6036 // default terrain '.' and
6037 // non-default field symbol -> field symbol overrides terrain
6038 sym = field_symbol[0];
6039 }
6040 tercol = fe->color();
6041 }
6042 }
6043
6044 // TODO: change the local variable sym to std::string and use it instead of this hack.
6045 // Currently this are different variables because terrain/... uses int as symbol type and
6046 // item now use string. Ideally they should all be strings.
6047 std::string item_sym;
6048
6049 // If there are items here, draw those instead
6050 if( param.show_items() && curr_maptile.get_item_count() > 0 && sees_some_items( p, g->u ) ) {
6051 // if there's furniture/terrain/trap/fields (sym!='.')
6052 // and we should not override it, then only highlight the square
6053 if( sym != '.' && sym != '%' && !draw_item_sym ) {
6054 hi = true;
6055 } else {
6056 // otherwise override with the symbol of the last item
6057 item_sym = curr_maptile.get_uppermost_item().symbol();
6058 if( !draw_item_sym ) {
6059 tercol = curr_maptile.get_uppermost_item().color();
6060 }
6061 if( curr_maptile.get_item_count() > 1 ) {
6062 param.highlight( !param.highlight() );
6063 }
6064 }
6065 }
6066
6067 int memory_sym = sym;
6068 int veh_part = 0;
6069 const vehicle *veh = veh_at_internal( p, veh_part );
6070 if( veh != nullptr ) {
6071 sym = special_symbol( veh->face.dir_symbol( veh->part_sym( veh_part ) ) );
6072 tercol = veh->part_color( veh_part );
6073 item_sym.clear(); // clear the item symbol so `sym` is used instead.
6074
6075 if( !veh->forward_velocity() && !veh->player_in_control( g->u ) ) {
6076 memory_sym = sym;
6077 }
6078 }
6079
6080 if( param.memorize() && check_and_set_seen_cache( p ) ) {
6081 g->u.memorize_symbol( getabs( p ), memory_sym );
6082 }
6083
6084 // If there's graffiti here, change background color
6085 if( curr_maptile.has_graffiti() ) {
6086 graf = true;
6087 }
6088
6089 const auto u_vision = g->u.get_vision_modes();
6090 if( u_vision[BOOMERED] ) {
6091 tercol = c_magenta;
6092 } else if( u_vision[NV_GOGGLES] ) {
6093 tercol = param.bright_light() ? c_white : c_light_green;
6094 } else if( param.low_light() ) {
6095 tercol = c_dark_gray;
6096 } else if( u_vision[DARKNESS] ) {
6097 tercol = c_dark_gray;
6098 }
6099
6100 if( param.highlight() ) {
6101 tercol = invert_color( tercol );
6102 } else if( hi ) {
6103 tercol = hilite( tercol );
6104 } else if( graf ) {
6105 tercol = red_background( tercol );
6106 }
6107
6108 if( item_sym.empty() && sym == ' ' ) {
6109 if( !zlevels || p.z <= -OVERMAP_DEPTH || !curr_ter.has_flag( TFLAG_NO_FLOOR ) ) {
6110 // Print filler symbol
6111 sym = ' ';
6112 tercol = c_black;
6113 } else {
6114 // Draw tile underneath this one instead
6115 return false;
6116 }
6117 }
6118
6119 if( params.output() ) {
6120 if( item_sym.empty() ) {
6121 wputch( w, tercol, sym );
6122 } else {
6123 wprintz( w, tercol, item_sym );
6124 }
6125 }
6126 return true;
6127}
nc_color color() const
Definition: field.cpp:94
field_entry * find_field(const field_type_id &field_type_to_find)
Returns a field entry corresponding to the field_type_id parameter passed in.
Definition: field.cpp:153
field_type_id displayed_field_type() const
Returns field type that should be drawn.
Definition: field.cpp:275
unsigned int field_count() const
Definition: field.cpp:246
bool check_and_set_seen_cache(const tripoint &p) const
Definition: map.cpp:8876
bool sees_some_items(const tripoint &p, const Creature &who) const
Check if creature can see some items at p.
Definition: map.cpp:4795
nc_color part_color(int p, bool exact=false) const
bool player_in_control(const Character &p) const
Definition: vehicle.cpp:278
float forward_velocity() const
nc_color red_background(const nc_color &c)
Definition: color.cpp:515
nc_color hilite(const nc_color &c)
Definition: color.cpp:509
@ TFLAG_SWIMMABLE
Definition: mapdata.h:279
void wprintz(const catacurses::window &w, const nc_color &FG, const std::string &text)
Definition: output.cpp:2089
constexpr drawsq_params & show_items(bool v)
Whether to draw items on the tile.
Definition: map.h:212
int priority
Definition: field_type.h:176
std::string get_symbol(int level=0) const
Definition: field_type.h:195
furn_str_id id
Definition: mapdata.h:500
nc_color color
Definition: trap.h:93
int sym
Definition: trap.h:92

References BOOMERED, drawsq_params::bright_light(), c_black, c_dark_gray, c_light_green, c_magenta, c_white, trap::can_see(), check_and_set_seen_cache(), field_entry::color(), item::color(), map_data_common_t::color(), trap::color, DARKNESS, determine_wall_corner(), tileray::dir_symbol(), field::displayed_field_type(), vehicle::face, field::field_count(), field::find_field(), vehicle::forward_velocity(), g, maptile::get_field(), maptile::get_furn_t(), maptile::get_item_count(), field_type::get_symbol(), maptile::get_ter_t(), maptile::get_trap(), maptile::get_uppermost_item(), getabs(), map_data_common_t::has_flag(), maptile::has_graffiti(), drawsq_params::highlight(), hilite(), furn_t::id, invert_color(), drawsq_params::low_light(), drawsq_params::memorize(), NV_GOGGLES, int_id< T >::obj(), drawsq_params::output(), OVERMAP_DEPTH, vehicle::part_color(), vehicle::part_sym(), vehicle::player_in_control(), field_type::priority, red_background(), rng(), sees_some_items(), drawsq_params::show_items(), special_symbol(), trap::sym, item::symbol(), map_data_common_t::symbol(), TFLAG_AUTO_WALL_SYMBOL, TFLAG_DEEP_WATER, TFLAG_NO_FLOOR, TFLAG_SWIMMABLE, veh_at_internal(), wprintz(), wputch(), tripoint::z, and zlevels.

Referenced by draw(), and drawsq().

◆ draw_mine()

void map::draw_mine ( mapgendata dat)
protected

Definition at line 4793 of file mapgen.cpp.

4794{
4795 const oter_id &terrain_type = dat.terrain_type();
4796 if( terrain_type == "mine" || terrain_type == "mine_down" ) {
4797 if( is_ot_match( "mine", dat.north(), ot_match_type::prefix ) ) {
4798 dat.n_fac = ( one_in( 10 ) ? 0 : -2 );
4799 } else {
4800 dat.n_fac = 4;
4801 }
4802 if( is_ot_match( "mine", dat.east(), ot_match_type::prefix ) ) {
4803 dat.e_fac = ( one_in( 10 ) ? 0 : -2 );
4804 } else {
4805 dat.e_fac = 4;
4806 }
4807 if( is_ot_match( "mine", dat.south(), ot_match_type::prefix ) ) {
4808 dat.s_fac = ( one_in( 10 ) ? 0 : -2 );
4809 } else {
4810 dat.s_fac = 4;
4811 }
4812 if( is_ot_match( "mine", dat.west(), ot_match_type::prefix ) ) {
4813 dat.w_fac = ( one_in( 10 ) ? 0 : -2 );
4814 } else {
4815 dat.w_fac = 4;
4816 }
4817
4818 for( int i = 0; i < SEEX * 2; i++ ) {
4819 for( int j = 0; j < SEEY * 2; j++ ) {
4820 if( i >= dat.w_fac + rng( 0, 2 ) && i <= EAST_EDGE - dat.e_fac - rng( 0, 2 ) &&
4821 j >= dat.n_fac + rng( 0, 2 ) && j <= SOUTH_EDGE - dat.s_fac - rng( 0, 2 ) &&
4822 i + j >= 4 && ( SEEX * 2 - i ) + ( SEEY * 2 - j ) >= 6 ) {
4823 ter_set( point( i, j ), t_rock_floor );
4824 } else {
4825 ter_set( point( i, j ), t_rock );
4826 }
4827 }
4828 }
4829
4830 // Not an entrance; maybe some hazards!
4831 switch( rng( 0, 4 ) ) {
4832 case 0:
4833 break; // Nothing! Lucky!
4834
4835 case 1: {
4836 // Toxic gas
4837 point gas_vent_location( rng( 9, 14 ), rng( 9, 14 ) );
4838 ter_set( point( gas_vent_location ), t_rock );
4839 add_field( { gas_vent_location, abs_sub.z }, fd_gas_vent, 2 );
4840 }
4841 break;
4842
4843 case 2: {
4844 // Lava
4845 point start_location( rng( 6, SEEX ), rng( 6, SEEY ) );
4846 point end_location( rng( SEEX + 1, SEEX * 2 - 7 ), rng( SEEY + 1, SEEY * 2 - 7 ) );
4847 const int num = rng( 2, 4 );
4848 for( int i = 0; i < num; i++ ) {
4849 int lx1 = start_location.x + rng( -1, 1 );
4850 int lx2 = end_location.x + rng( -1, 1 );
4851 int ly1 = start_location.y + rng( -1, 1 );
4852 int ly2 = end_location.y + rng( -1, 1 );
4853 line( this, t_lava, point( lx1, ly1 ), point( lx2, ly2 ) );
4854 }
4856 tripoint( end_location,
4857 abs_sub.z ) ) ) {
4858 if( ter( ore ) == t_rock_floor && one_in( 10 ) ) {
4859 spawn_item( ore, "chunk_sulfur" );
4860 }
4861 }
4862 }
4863 break;
4864
4865 case 3: {
4866 // Wrecked equipment
4867 point wreck_location( rng( 9, 14 ), rng( 9, 14 ) );
4868 for( int i = wreck_location.x - 3; i < wreck_location.x + 3; i++ ) {
4869 for( int j = wreck_location.y - 3; j < wreck_location.y + 3; j++ ) {
4870 if( !one_in( 4 ) ) {
4871 make_rubble( tripoint( i, j, abs_sub.z ), f_wreckage, true );
4872 }
4873 }
4874 }
4875 place_items( item_group_id( "wreckage" ), 70, wreck_location + point( -3, -3 ),
4876 wreck_location + point( 2, 2 ), false, calendar::start_of_cataclysm );
4877 }
4878 break;
4879
4880 case 4: {
4881 // Dead miners
4882 const int num_bodies = rng( 4, 8 );
4883 for( int i = 0; i < num_bodies; i++ ) {
4884 if( const auto body = random_point( *this, [this]( const tripoint & p ) {
4885 return move_cost( p ) == 2;
4886 } ) ) {
4887 add_item( *body, item::make_corpse() );
4888 place_items( item_group_id( "mon_zombie_miner_death_drops" ), 100, *body, *body,
4890 }
4891 }
4892 }
4893 break;
4894
4895 }
4896
4897 if( terrain_type == "mine_down" ) { // Don't forget to build a slope down!
4898 std::vector<direction> open;
4899 if( dat.n_fac == 4 ) {
4900 open.push_back( direction::NORTH );
4901 }
4902 if( dat.e_fac == 4 ) {
4903 open.push_back( direction::EAST );
4904 }
4905 if( dat.s_fac == 4 ) {
4906 open.push_back( direction::SOUTH );
4907 }
4908 if( dat.w_fac == 4 ) {
4909 open.push_back( direction::WEST );
4910 }
4911
4912 if( open.empty() ) { // We'll have to build it in the center
4913 int tries = 0;
4914 point p;
4915 bool okay = true;
4916 do {
4917 p.x = rng( SEEX - 6, SEEX + 1 );
4918 p.y = rng( SEEY - 6, SEEY + 1 );
4919 okay = true;
4920 for( int i = p.x; ( i <= p.x + 5 ) && okay; i++ ) {
4921 for( int j = p.y; ( j <= p.y + 5 ) && okay; j++ ) {
4922 if( ter( point( i, j ) ) != t_rock_floor ) {
4923 okay = false;
4924 }
4925 }
4926 }
4927 if( !okay ) {
4928 tries++;
4929 }
4930 } while( !okay && tries < 10 );
4931 if( tries == 10 ) { // Clear the area around the slope down
4932 square( this, t_rock_floor, p, p + point( 5, 5 ) );
4933 }
4934 // NOLINTNEXTLINE(cata-use-named-point-constants)
4935 square( this, t_slope_down, p + point( 1, 1 ), p + point( 2, 2 ) );
4936 } else { // We can build against a wall
4937 switch( random_entry( open ) ) {
4938 case direction::NORTH:
4939 square( this, t_rock_floor, point( SEEX - 3, 6 ), point( SEEX + 2, SEEY ) );
4940 line( this, t_slope_down, point( SEEX - 2, 6 ), point( SEEX + 1, 6 ) );
4941 break;
4942 case direction::EAST:
4943 square( this, t_rock_floor, point( SEEX + 1, SEEY - 3 ), point( SEEX * 2 - 7, SEEY + 2 ) );
4944 line( this, t_slope_down, point( SEEX * 2 - 7, SEEY - 2 ), point( SEEX * 2 - 7, SEEY + 1 ) );
4945 break;
4946 case direction::SOUTH:
4947 square( this, t_rock_floor, point( SEEX - 3, SEEY + 1 ), point( SEEX + 2, SEEY * 2 - 7 ) );
4948 line( this, t_slope_down, point( SEEX - 2, SEEY * 2 - 7 ), point( SEEX + 1, SEEY * 2 - 7 ) );
4949 break;
4950 case direction::WEST:
4951 square( this, t_rock_floor, point( 6, SEEY - 3 ), point( SEEX, SEEY + 2 ) );
4952 line( this, t_slope_down, point( 6, SEEY - 2 ), point( 6, SEEY + 1 ) );
4953 break;
4954 default:
4955 break;
4956 }
4957 }
4958 } // Done building a slope down
4959
4960 if( dat.above() == "mine_down" ) { // Don't forget to build a slope up!
4961 std::vector<direction> open;
4962 if( dat.n_fac == 6 && ter( point( SEEX, 6 ) ) != t_slope_down ) {
4963 open.push_back( direction::NORTH );
4964 }
4965 if( dat.e_fac == 6 && ter( point( SEEX * 2 - 7, SEEY ) ) != t_slope_down ) {
4966 open.push_back( direction::EAST );
4967 }
4968 if( dat.s_fac == 6 && ter( point( SEEX, SEEY * 2 - 7 ) ) != t_slope_down ) {
4969 open.push_back( direction::SOUTH );
4970 }
4971 if( dat.w_fac == 6 && ter( point( 6, SEEY ) ) != t_slope_down ) {
4972 open.push_back( direction::WEST );
4973 }
4974
4975 if( open.empty() ) { // We'll have to build it in the center
4976 int tries = 0;
4977 point p;
4978 bool okay = true;
4979 do {
4980 p.x = rng( SEEX - 6, SEEX + 1 );
4981 p.y = rng( SEEY - 6, SEEY + 1 );
4982 okay = true;
4983 for( int i = p.x; ( i <= p.x + 5 ) && okay; i++ ) {
4984 for( int j = p.y; ( j <= p.y + 5 ) && okay; j++ ) {
4985 if( ter( point( i, j ) ) != t_rock_floor ) {
4986 okay = false;
4987 }
4988 }
4989 }
4990 if( !okay ) {
4991 tries++;
4992 }
4993 } while( !okay && tries < 10 );
4994 if( tries == 10 ) { // Clear the area around the slope down
4995 square( this, t_rock_floor, p, p + point( 5, 5 ) );
4996 }
4997 // NOLINTNEXTLINE(cata-use-named-point-constants)
4998 square( this, t_slope_up, p + point( 1, 1 ), p + point( 2, 2 ) );
4999
5000 } else { // We can build against a wall
5001 switch( random_entry( open ) ) {
5002 case direction::NORTH:
5003 line( this, t_slope_up, point( SEEX - 2, 6 ), point( SEEX + 1, 6 ) );
5004 break;
5005 case direction::EAST:
5006 line( this, t_slope_up, point( SEEX * 2 - 7, SEEY - 2 ), point( SEEX * 2 - 7, SEEY + 1 ) );
5007 break;
5008 case direction::SOUTH:
5009 line( this, t_slope_up, point( SEEX - 2, SEEY * 2 - 7 ), point( SEEX + 1, SEEY * 2 - 7 ) );
5010 break;
5011 case direction::WEST:
5012 line( this, t_slope_up, point( 6, SEEY - 2 ), point( 6, SEEY + 1 ) );
5013 break;
5014 default:
5015 break;
5016 }
5017 }
5018 } // Done building a slope up
5019 } else if( terrain_type == "mine_finale" ) {
5020 // Set up the basic chamber
5021 for( int i = 0; i < SEEX * 2; i++ ) {
5022 for( int j = 0; j < SEEY * 2; j++ ) {
5023 if( i > rng( 1, 3 ) && i < SEEX * 2 - rng( 2, 4 ) &&
5024 j > rng( 1, 3 ) && j < SEEY * 2 - rng( 2, 4 ) ) {
5025 ter_set( point( i, j ), t_rock_floor );
5026 } else {
5027 ter_set( point( i, j ), t_rock );
5028 }
5029 }
5030 }
5031
5032 // Now draw the entrance(s)
5033 if( dat.north() == "mine" ) {
5034 square( this, t_rock_floor, point( SEEX, 0 ), point( SEEX + 1, 3 ) );
5035 }
5036
5037 if( dat.east() == "mine" ) {
5038 square( this, t_rock_floor, point( SEEX * 2 - 4, SEEY ), point( EAST_EDGE, SEEY + 1 ) );
5039 }
5040
5041 if( dat.south() == "mine" ) {
5042 square( this, t_rock_floor, point( SEEX, SEEY * 2 - 4 ), point( SEEX + 1, SOUTH_EDGE ) );
5043 }
5044
5045 if( dat.west() == "mine" ) {
5046 square( this, t_rock_floor, point( 0, SEEY ), point( 3, SEEY + 1 ) );
5047 }
5048
5049 // Now, pick and generate a type of finale!
5050 // The Thing dog
5051 const int num_bodies = rng( 4, 8 );
5052 for( int i = 0; i < num_bodies; i++ ) {
5053 point p3( rng( 4, SEEX * 2 - 5 ), rng( 4, SEEX * 2 - 5 ) );
5054 add_item( p3, item::make_corpse() );
5055 place_items( item_group_id( "mon_zombie_miner_death_drops" ), 60, p3,
5056 p3, false, calendar::start_of_cataclysm );
5057 }
5058 place_spawns( GROUP_DOG_THING, 1, point( SEEX, SEEX ), point( SEEX + 1, SEEX + 1 ), 1, true, true );
5059 spawn_artifact( tripoint( rng( SEEX, SEEX + 1 ), rng( SEEY, SEEY + 1 ), abs_sub.z ) );
5060 }
5061}
void spawn_artifact(const tripoint &p)
Definition: map.cpp:4243
static void open()
furn_id f_wreckage
Definition: mapdata.cpp:1099
ter_id t_rock
Definition: mapdata.cpp:675
ter_id t_lava
Definition: mapdata.cpp:697
static const mongroup_id GROUP_DOG_THING("GROUP_DOG_THING")
void square(map *m, const ter_id &type, point p1, point p2)
Definition: mapgen.cpp:6508

References mapgendata::above(), abs_sub, add_field(), add_item(), mapgendata::e_fac, EAST, mapgendata::east(), EAST_EDGE, f_wreckage, fd_gas_vent, GROUP_DOG_THING, is_ot_match(), line(), item::make_corpse(), make_rubble(), move_cost(), mapgendata::n_fac, NORTH, mapgendata::north(), num, one_in(), open(), place_items(), place_spawns(), points_in_rectangle(), prefix, random_entry(), random_point(), rng(), mapgendata::s_fac, SEEX, SEEY, SOUTH, mapgendata::south(), SOUTH_EDGE, spawn_artifact(), spawn_item(), square(), calendar::start_of_cataclysm, t_lava, t_rock, t_rock_floor, t_slope_down, t_slope_up, ter(), ter_set(), mapgendata::terrain_type(), mapgendata::w_fac, WEST, mapgendata::west(), point::x, point::y, and tripoint::z.

Referenced by draw_map().

◆ draw_office_tower()

void map::draw_office_tower ( mapgendata dat)
protected

Definition at line 2958 of file mapgen.cpp.

2959{
2960 const oter_id &terrain_type = dat.terrain_type();
2961 const auto place_office_chairs = [&]() {
2962 int num_chairs = rng( 0, 6 );
2963 for( int i = 0; i < num_chairs; i++ ) {
2964 add_vehicle( vproto_id( "swivel_chair" ), point( rng( 6, 16 ), rng( 6, 16 ) ),
2965 0_degrees, -1, -1, false );
2966 }
2967 };
2968
2969 const auto ter_key = mapf::ter_bind( "E > < R # X G C , _ r V H 6 x % ^ . - | "
2970 "t + = D w T S e o h c d l s", t_elevator, t_stairs_down,
2978 const auto fur_key = mapf::furn_bind( "E > < R # X G C , _ r V H 6 x % ^ . - | "
2979 "t + = D w T S e o h c d l s", f_null, f_null, f_null,
2985 f_null );
2986 const auto b_ter_key = mapf::ter_bind( "E s > < R # X G C , . r V H 6 x % ^ _ - | "
2987 "t + = D w T S e o h c d l", t_elevator, t_rock,
2995 t_floor, t_floor );
2996 const auto b_fur_key = mapf::furn_bind( "E s > < R # X G C , . r V H 6 x % ^ _ - | "
2997 "t + = D w T S e o h c d l", f_null, f_null, f_null,
3004
3005 if( terrain_type == "office_tower_1_entrance" ) {
3006 dat.fill_groundcover();
3008 "ss%|....+...|...|EEED...\n"
3009 "ss%|----|...|...|EEx|...\n"
3010 "ss%Vcdc^|...|-+-|---|...\n"
3011 "ss%Vch..+...............\n"
3012 "ss%V....|...............\n"
3013 "ss%|----|-|-+--ccc--|...\n"
3014 "ss%|..C..C|.....h..r|-+-\n"
3015 "sss=......+..h.....r|...\n"
3016 "ss%|r..CC.|.ddd....r|T.S\n"
3017 "ss%|------|---------|---\n"
3018 "ss%|####################\n"
3019 "ss%|#|------||------|###\n"
3020 "ss%|#|......||......|###\n"
3021 "ss%|||......||......|###\n"
3022 "ss%||x......||......||##\n"
3023 "ss%|||......||......x|##\n"
3024 "ss%|#|......||......||##\n"
3025 "ss%|#|......||......|###\n"
3026 "ss%|#|XXXXXX||XXXXXX|###\n"
3027 "ss%|-|__,,__||__,,__|---\n"
3028 "ss%% x_,,,,_ __,,__ %%\n"
3029 "ss __,,__ _,,,,_ \n"
3030 "ssssss__,,__ss__,,__ssss\n"
3031 "ssssss______ss______ssss\n", ter_key, fur_key );
3032 place_items( item_group_id( "office" ), 75, point( 4, 2 ), point( 6, 2 ), false,
3034 place_items( item_group_id( "office" ), 75, point( 19, 6 ), point( 19, 6 ), false,
3036 place_items( item_group_id( "office" ), 75, point( 12, 8 ), point( 14, 8 ), false,
3038 if( dat.monster_density() > 1 ) {
3040 } else {
3041 place_spawns( GROUP_PLAIN, 2, point( 15, 1 ), point( 22, 7 ), 1, true );
3042 place_spawns( GROUP_PLAIN, 2, point( 15, 1 ), point( 22, 7 ), 0.15 );
3043 place_spawns( GROUP_ZOMBIE_COP, 2, point( 10, 10 ), point( 14, 10 ), 0.1 );
3044 }
3045 place_office_chairs();
3046
3047 if( dat.north() == "office_tower_1" && dat.west() == "office_tower_1" ) {
3048 rotate( 3 );
3049 } else if( dat.north() == "office_tower_1" && dat.east() == "office_tower_1" ) {
3050 rotate( 0 );
3051 } else if( dat.south() == "office_tower_1" && dat.east() == "office_tower_1" ) {
3052 rotate( 1 );
3053 } else if( dat.west() == "office_tower_1" && dat.south() == "office_tower_1" ) {
3054 rotate( 2 );
3055 }
3056 } else if( terrain_type == "office_tower_1" ) {
3057 // Init to grass & dirt;
3058 dat.fill_groundcover();
3059 if( ( dat.south() == "office_tower_1_entrance" && dat.east() == "office_tower_1" ) ||
3060 ( dat.north() == "office_tower_1" && dat.east() == "office_tower_1_entrance" ) ||
3061 ( dat.west() == "office_tower_1" && dat.north() == "office_tower_1_entrance" ) ||
3062 ( dat.south() == "office_tower_1" && dat.west() == "office_tower_1_entrance" ) ) {
3064 " ssssssssssssssssssssssss\n"
3065 "ssssssssssssssssssssssss\n"
3066 "ss \n"
3067 "ss%%%%%%%%%%%%%%%%%%%%%%\n"
3068 "ss%|-HH-|-HH-|-HH-|HH|--\n"
3069 "ss%Vdcxl|dxdl|lddx|..|.S\n"
3070 "ss%Vdh..|dh..|..hd|..+..\n"
3071 "ss%|-..-|-..-|-..-|..|--\n"
3072 "ss%V.................|.T\n"
3073 "ss%V.................|..\n"
3074 "ss%|-..-|-..-|-..-|..|--\n"
3075 "ss%V.h..|..hd|..hd|..|..\n"
3076 "ss%Vdxdl|^dxd|.xdd|..G..\n"
3077 "ss%|----|----|----|..G..\n"
3078 "ss%|llll|..htth......|..\n"
3079 "ss%V.................|..\n"
3080 "ss%V.ddd..........|+-|..\n"
3081 "ss%|..hd|.hh.ceocc|.l|..\n"
3082 "ss%|----|---------|--|..\n"
3083 "ss%Vcdcl|...............\n"
3084 "ss%V.h..+...............\n"
3085 "ss%V...^|...|---|---|...\n"
3086 "ss%|----|...|.R>|EEE|...\n"
3087 "ss%|rrrr|...|.R.|EEED...\n", ter_key, fur_key );
3088 if( dat.monster_density() > 1 ) {
3090 } else {
3091 place_spawns( GROUP_PLAIN, 1, point( 5, 7 ), point( 15, 20 ), 0.1 );
3092 }
3093 place_items( item_group_id( "office" ), 75, point( 4, 23 ), point( 7, 23 ), false,
3095 place_items( item_group_id( "office" ), 75, point( 4, 19 ), point( 7, 19 ), false,
3097 place_items( item_group_id( "office" ), 75, point( 4, 14 ), point( 7, 14 ), false,
3099 place_items( item_group_id( "office" ), 75, point( 5, 16 ), point( 7, 16 ), false,
3101 place_items( item_group_id( "fridge" ), 80, point( 14, 17 ), point( 14, 17 ), false,
3103 place_items( item_group_id( "cleaning" ), 75, point( 19, 17 ), point( 20, 17 ), false,
3105 place_items( item_group_id( "cubical_office" ), 75, point( 6, 12 ), point( 7, 12 ), false,
3107 place_items( item_group_id( "cubical_office" ), 75, point( 12, 11 ), point( 12, 12 ), false,
3109 place_items( item_group_id( "cubical_office" ), 75, point( 16, 11 ), point( 17, 12 ), false,
3111 place_items( item_group_id( "cubical_office" ), 75, point( 4, 5 ), point( 5, 5 ), false,
3113 place_items( item_group_id( "cubical_office" ), 75, point( 11, 5 ), point( 12, 5 ), false,
3115 place_items( item_group_id( "cubical_office" ), 75, point( 14, 5 ), point( 16, 5 ), false,
3117 place_office_chairs();
3118
3119 if( dat.west() == "office_tower_1_entrance" ) {
3120 rotate( 1 );
3121 }
3122 if( dat.north() == "office_tower_1_entrance" ) {
3123 rotate( 2 );
3124 }
3125 if( dat.east() == "office_tower_1_entrance" ) {
3126 rotate( 3 );
3127 }
3128 } else if( ( dat.west() == "office_tower_1_entrance" && dat.north() == "office_tower_1" ) ||
3129 ( dat.north() == "office_tower_1_entrance" && dat.east() == "office_tower_1" ) ||
3130 ( dat.west() == "office_tower_1" && dat.south() == "office_tower_1_entrance" ) ||
3131 ( dat.south() == "office_tower_1" && dat.east() == "office_tower_1_entrance" ) ) {
3133 "...DEEE|...|..|-----|%ss\n"
3134 "...|EEE|...|..|^...lV%ss\n"
3135 "...|---|-+-|......hdV%ss\n"
3136 "...........G..|..dddV%ss\n"
3137 "...........G..|-----|%ss\n"
3138 ".......|---|..|...ddV%ss\n"
3139 "|+-|...|...+......hdV%ss\n"
3140 "|.l|...|rr.|.^|l...dV%ss\n"
3141 "|--|...|---|--|-----|%ss\n"
3142 "|...........c.......V%ss\n"
3143 "|.......cxh.c.#####.Vsss\n"
3144 "|.......ccccc.......Gsss\n"
3145 "|...................Gsss\n"
3146 "|...................Vsss\n"
3147 "|#..................Gsss\n"
3148 "|#..................Gsss\n"
3149 "|#..................Vsss\n"
3150 "|#............#####.V%ss\n"
3151 "|...................|%ss\n"
3152 "--HHHHHGGHHGGHHHHH--|%ss\n"
3153 "%%%%% ssssssss %%%%%%%ss\n"
3154 " ssssssss ss\n"
3155 "ssssssssssssssssssssssss\n"
3156 "ssssssssssssssssssssssss\n", ter_key, fur_key );
3157 place_items( item_group_id( "office" ), 75, point( 19, 1 ), point( 19, 3 ), false,
3159 place_items( item_group_id( "office" ), 75, point( 17, 3 ), point( 18, 3 ), false,
3161 place_items( item_group_id( "office" ), 90, point( 8, 7 ), point( 9, 7 ), false,
3163 place_items( item_group_id( "cubical_office" ), 75, point( 19, 5 ), point( 19, 7 ), false,
3165 place_items( item_group_id( "cleaning" ), 80, point( 1, 7 ), point( 2, 7 ), false,
3167 if( dat.monster_density() > 1 ) {
3168 place_spawns( GROUP_ZOMBIE, 2, point_zero, point( 14, 10 ), dat.monster_density() );
3169 } else {
3170 place_spawns( GROUP_PLAIN, 1, point( 10, 10 ), point( 14, 10 ), 0.15 );
3171 place_spawns( GROUP_ZOMBIE_COP, 2, point( 10, 10 ), point( 14, 10 ), 0.1 );
3172 }
3173 place_office_chairs();
3174
3175 if( dat.north() == "office_tower_1_entrance" ) {
3176 rotate( 1 );
3177 }
3178 if( dat.east() == "office_tower_1_entrance" ) {
3179 rotate( 2 );
3180 }
3181 if( dat.south() == "office_tower_1_entrance" ) {
3182 rotate( 3 );
3183 }
3184 } else {
3186 "ssssssssssssssssssssssss\n"
3187 "ssssssssssssssssssssssss\n"
3188 " ss\n"
3189 "%%%%%%%%%%%%%%%%%%%%%%ss\n"
3190 "--|---|--HHHH-HHHH--|%ss\n"
3191 ".T|..l|............^|%ss\n"
3192 "..|-+-|...hhhhhhh...V%ss\n"
3193 "--|...G...ttttttt...V%ss\n"
3194 ".S|...G...ttttttt...V%ss\n"
3195 "..+...|...hhhhhhh...V%ss\n"
3196 "--|...|.............|%ss\n"
3197 "..|...|-------------|%ss\n"
3198 "..G....|l.......dxd^|%ss\n"
3199 "..G....G...h....dh..V%ss\n"
3200 "..|....|............V%ss\n"
3201 "..|....|------|llccc|%ss\n"
3202 "..|...........|-----|%ss\n"
3203 "..|...........|...ddV%ss\n"
3204 "..|----|---|......hdV%ss\n"
3205 ".......+...|..|l...dV%ss\n"
3206 ".......|rrr|..|-----|%ss\n"
3207 "...|---|---|..|l.dddV%ss\n"
3208 "...|xEE|.R>|......hdV%ss\n"
3209 "...DEEE|.R.|..|.....V%ss\n", ter_key, fur_key );
3210 spawn_item( point( 18, 15 ), "record_accounting" );
3211 place_items( item_group_id( "cleaning" ), 75, point( 3, 5 ), point( 5, 5 ), false,
3213 place_items( item_group_id( "office" ), 75, point( 10, 7 ), point( 16, 8 ), false,
3215 place_items( item_group_id( "cubical_office" ), 75, point( 15, 15 ), point( 19, 15 ), false,
3217 place_items( item_group_id( "cubical_office" ), 75, point( 16, 12 ), point( 16, 13 ), false,
3219 place_items( item_group_id( "cubical_office" ), 75, point( 17, 19 ), point( 19, 19 ), false,
3221 place_items( item_group_id( "office" ), 75, point( 17, 21 ), point( 19, 21 ), false,
3223 place_items( item_group_id( "office" ), 75, point( 16, 11 ), point( 17, 12 ), false,
3225 place_items( item_group_id( "cleaning" ), 75, point( 8, 20 ), point( 10, 20 ), false,
3227 if( dat.monster_density() > 1 ) {
3229 } else {
3230 place_spawns( GROUP_PLAIN, 1, point_zero, point( 9, 15 ), 0.1 );
3231 }
3232 place_office_chairs();
3233
3234 if( dat.west() == "office_tower_1" && dat.north() == "office_tower_1" ) {
3235 rotate( 1 );
3236 } else if( dat.east() == "office_tower_1" && dat.north() == "office_tower_1" ) {
3237 rotate( 2 );
3238 } else if( dat.east() == "office_tower_1" && dat.south() == "office_tower_1" ) {
3239 rotate( 3 );
3240 }
3241 }
3242 } else if( terrain_type == "office_tower_b_entrance" ) {
3243 dat.fill_groundcover();
3245 "sss|........|...|EEED___\n"
3246 "sss|........|...|EEx|___\n"
3247 "sss|........|-+-|---|HHG\n"
3248 "sss|....................\n"
3249 "sss|....................\n"
3250 "sss|....................\n"
3251 "sss|....................\n"
3252 "sss|....,,......,,......\n"
3253 "sss|...,,,,.....,,......\n"
3254 "sss|....,,.....,,,,..xS.\n"
3255 "sss|....,,......,,...SS.\n"
3256 "sss|-|XXXXXX||XXXXXX|---\n"
3257 "sss|s|EEEEEE||EEEEEE|sss\n"
3258 "sss|||EEEEEE||EEEEEE|sss\n"
3259 "sss||xEEEEEE||EEEEEE||ss\n"
3260 "sss|||EEEEEE||EEEEEEx|ss\n"
3261 "sss|s|EEEEEE||EEEEEE||ss\n"
3262 "sss|s|EEEEEE||EEEEEE|sss\n"
3263 "sss|s|------||------|sss\n"
3264 "sss|--------------------\n"
3265 "ssssssssssssssssssssssss\n"
3266 "ssssssssssssssssssssssss\n"
3267 "ssssssssssssssssssssssss\n"
3268 "ssssssssssssssssssssssss\n", ter_key, fur_key );
3269 if( dat.monster_density() > 1 ) {
3271 } else {
3273 }
3274 if( dat.north() == "office_tower_b" && dat.west() == "office_tower_b" ) {
3275 rotate( 3 );
3276 } else if( dat.north() == "office_tower_b" && dat.east() == "office_tower_b" ) {
3277 rotate( 0 );
3278 } else if( dat.south() == "office_tower_b" && dat.east() == "office_tower_b" ) {
3279 rotate( 1 );
3280 } else if( dat.west() == "office_tower_b" && dat.south() == "office_tower_b" ) {
3281 rotate( 2 );
3282 }
3283 } else if( terrain_type == "office_tower_b" ) {
3284 // Init to grass & dirt;
3285 dat.fill_groundcover();
3286 if( ( dat.south() == "office_tower_b_entrance" && dat.east() == "office_tower_b" ) ||
3287 ( dat.north() == "office_tower_b" && dat.east() == "office_tower_b_entrance" ) ||
3288 ( dat.west() == "office_tower_b" && dat.north() == "office_tower_b_entrance" ) ||
3289 ( dat.south() == "office_tower_b" && dat.west() == "office_tower_b_entrance" ) ) {
3291 "ssssssssssssssssssssssss\n"
3292 "ssssssssssssssssssssssss\n"
3293 "sss|--------------------\n"
3294 "sss|,.....,.....,.....,S\n"
3295 "sss|,.....,.....,.....,S\n"
3296 "sss|,.....,.....,.....,S\n"
3297 "sss|,.....,.....,.....,S\n"
3298 "sss|,.....,.....,.....,S\n"
3299 "sss|,.....,.....,.....,S\n"
3300 "sss|....................\n"
3301 "sss|....................\n"
3302 "sss|....................\n"
3303 "sss|....................\n"
3304 "sss|....................\n"
3305 "sss|....................\n"
3306 "sss|...,,...,....,....,S\n"
3307 "sss|..,,,,..,....,....,S\n"
3308 "sss|...,,...,....,....,S\n"
3309 "sss|...,,...,....,....,S\n"
3310 "sss|........,....,....,S\n"
3311 "sss|........,....,....,S\n"
3312 "sss|........|---|---|HHG\n"
3313 "sss|........|.R<|EEE|___\n"
3314 "sss|........|.R.|EEED___\n", b_ter_key, b_fur_key );
3315 if( dat.monster_density() > 1 ) {
3317 } else {
3319 }
3320 if( dat.west() == "office_tower_b_entrance" ) {
3321 rotate( 1 );
3322 if( x_in_y( 1, 5 ) ) {
3323 add_vehicle( vproto_id( "car" ), point( 17, 7 ), 180_degrees );
3324 }
3325 if( x_in_y( 1, 3 ) ) {
3326 add_vehicle( vproto_id( "motorcycle" ), point( 17, 13 ), 180_degrees );
3327 }
3328 if( x_in_y( 1, 5 ) ) {
3329 if( one_in( 3 ) ) {
3330 add_vehicle( vproto_id( "fire_truck" ), point( 6, 13 ), 0_degrees );
3331 } else {
3332 add_vehicle( vproto_id( "pickup" ), point( 17, 19 ), 180_degrees );
3333 }
3334 }
3335 } else if( dat.north() == "office_tower_b_entrance" ) {
3336 rotate( 2 );
3337 if( x_in_y( 1, 5 ) ) {
3338 add_vehicle( vproto_id( "car" ), point( 10, 17 ), 270_degrees );
3339 }
3340 if( x_in_y( 1, 3 ) ) {
3341 add_vehicle( vproto_id( "motorcycle" ), point( 4, 18 ), 270_degrees );
3342 }
3343 if( x_in_y( 1, 5 ) ) {
3344 if( one_in( 3 ) ) {
3345 add_vehicle( vproto_id( "fire_truck" ), point( 6, 13 ), 0_degrees );
3346 } else {
3347 add_vehicle( vproto_id( "pickup" ), point( 16, 17 ), 270_degrees );
3348 }
3349 }
3350 } else if( dat.east() == "office_tower_b_entrance" ) {
3351 rotate( 3 );
3352 if( x_in_y( 1, 5 ) ) {
3353 add_vehicle( vproto_id( "car" ), point( 6, 4 ), 0_degrees );
3354 }
3355 if( x_in_y( 1, 3 ) ) {
3356 add_vehicle( vproto_id( "motorcycle" ), point( 6, 10 ), 180_degrees );
3357 }
3358 if( x_in_y( 1, 5 ) ) {
3359 add_vehicle( vproto_id( "pickup" ), point( 6, 16 ), 0_degrees );
3360 }
3361
3362 } else {
3363 if( x_in_y( 1, 5 ) ) {
3364 add_vehicle( vproto_id( "pickup" ), point( 7, 6 ), 90_degrees );
3365 }
3366 if( x_in_y( 1, 5 ) ) {
3367 add_vehicle( vproto_id( "car" ), point( 14, 6 ), 90_degrees );
3368 }
3369 if( x_in_y( 1, 3 ) ) {
3370 add_vehicle( vproto_id( "motorcycle" ), point( 19, 6 ), 90_degrees );
3371 }
3372 }
3373 } else if( ( dat.west() == "office_tower_b_entrance" && dat.north() == "office_tower_b" ) ||
3374 ( dat.north() == "office_tower_b_entrance" && dat.east() == "office_tower_b" ) ||
3375 ( dat.west() == "office_tower_b" && dat.south() == "office_tower_b_entrance" ) ||
3376 ( dat.south() == "office_tower_b" && dat.east() == "office_tower_b_entrance" ) ) {
3378 "___DEEE|...|...,,...|sss\n"
3379 "___|EEE|...|..,,,,..|sss\n"
3380 "GHH|---|-+-|...,,...|sss\n"
3381 "....................|sss\n"
3382 "....................|sss\n"
3383 "....................|sss\n"
3384 "....................|sss\n"
3385 "....................|sss\n"
3386 "....................|sss\n"
3387 "....................|sss\n"
3388 "....................|sss\n"
3389 "|...................|sss\n"
3390 "|...................|sss\n"
3391 "|,.....,.....,.....,|sss\n"
3392 "|,.....,.....,.....,|sss\n"
3393 "|,.....,.....,.....,|sss\n"
3394 "|,.....,.....,.....,|sss\n"
3395 "|,.....,.....,.....,|sss\n"
3396 "|,.....,.....,.....,|sss\n"
3397 "|-------------------|sss\n"
3398 "ssssssssssssssssssssssss\n"
3399 "ssssssssssssssssssssssss\n"
3400 "ssssssssssssssssssssssss\n"
3401 "ssssssssssssssssssssssss\n", b_ter_key, b_fur_key );
3402 if( dat.monster_density() > 1 ) {
3404 } else {
3406 }
3407 if( dat.north() == "office_tower_b_entrance" ) {
3408 rotate( 1 );
3409 if( x_in_y( 1, 5 ) ) {
3410 add_vehicle( vproto_id( "car" ), point( 8, 15 ), 0_degrees );
3411 }
3412 if( x_in_y( 1, 5 ) ) {
3413 add_vehicle( vproto_id( "pickup" ), point( 7, 10 ), 180_degrees );
3414 }
3415 if( x_in_y( 1, 3 ) ) {
3416 add_vehicle( vproto_id( "beetle" ), point( 7, 3 ), 0_degrees );
3417 }
3418 } else if( dat.east() == "office_tower_b_entrance" ) {
3419 rotate( 2 );
3420 if( x_in_y( 1, 5 ) ) {
3421 if( one_in( 3 ) ) {
3422 add_vehicle( vproto_id( "fire_truck" ), point( 6, 13 ), 0_degrees );
3423 } else {
3424 add_vehicle( vproto_id( "pickup" ), point( 7, 7 ), 270_degrees );
3425 }
3426 }
3427 if( x_in_y( 1, 5 ) ) {
3428 add_vehicle( vproto_id( "car" ), point( 13, 8 ), 90_degrees );
3429 }
3430 if( x_in_y( 1, 3 ) ) {
3431 add_vehicle( vproto_id( "beetle" ), point( 20, 7 ), 90_degrees );
3432 }
3433 } else if( dat.south() == "office_tower_b_entrance" ) {
3434 rotate( 3 );
3435 if( x_in_y( 1, 5 ) ) {
3436 add_vehicle( vproto_id( "pickup" ), point( 16, 7 ), 0_degrees );
3437 }
3438 if( x_in_y( 1, 5 ) ) {
3439 add_vehicle( vproto_id( "car" ), point( 15, 13 ), 180_degrees );
3440 }
3441 if( x_in_y( 1, 3 ) ) {
3442 add_vehicle( vproto_id( "beetle" ), point( 15, 20 ), 180_degrees );
3443 }
3444 } else {
3445 if( x_in_y( 1, 5 ) ) {
3446 add_vehicle( vproto_id( "pickup" ), point( 16, 16 ), 90_degrees );
3447 }
3448 if( x_in_y( 1, 5 ) ) {
3449 add_vehicle( vproto_id( "car" ), point( 9, 15 ), 270_degrees );
3450 }
3451 if( x_in_y( 1, 3 ) ) {
3452 add_vehicle( vproto_id( "beetle" ), point( 4, 16 ), 270_degrees );
3453 }
3454 }
3455 } else {
3457 "ssssssssssssssssssssssss\n"
3458 "ssssssssssssssssssssssss\n"
3459 "--------------------|sss\n"
3460 "S,.....,.....,.....,|sss\n"
3461 "S,.....,.....,.....,|sss\n"
3462 "S,.....,.....,.....,|sss\n"
3463 "S,.....,.....,.....,|sss\n"
3464 "S,.....,.....,.....,|sss\n"
3465 "S,.....,.....,.....,|sss\n"
3466 "....................|sss\n"
3467 "....................|sss\n"
3468 "....................|sss\n"
3469 "....................|sss\n"
3470 "....................|sss\n"
3471 "....................|sss\n"
3472 "S,....,....,........|sss\n"
3473 "S,....,....,........|sss\n"
3474 "S,....,....,........|sss\n"
3475 "S,....,....,........|sss\n"
3476 "S,....,....,........|sss\n"
3477 "S,....,....,........|sss\n"
3478 "GHH|---|---|........|sss\n"
3479 "___|xEE|.R<|........|sss\n"
3480 "___DEEE|.R.|...,,...|sss\n", b_ter_key, b_fur_key );
3481 if( dat.monster_density() > 1 ) {
3483 } else {
3485 }
3486 if( dat.west() == "office_tower_b" && dat.north() == "office_tower_b" ) {
3487 rotate( 1 );
3488 if( x_in_y( 1, 5 ) ) {
3489 if( one_in( 3 ) ) {
3490 add_vehicle( vproto_id( "cube_van" ), point( 17, 4 ), 180_degrees );
3491 } else {
3492 add_vehicle( vproto_id( "cube_van_cheap" ), point( 17, 4 ), 180_degrees );
3493 }
3494 }
3495 if( x_in_y( 1, 5 ) ) {
3496 add_vehicle( vproto_id( "pickup" ), point( 17, 10 ), 180_degrees );
3497 }
3498 if( x_in_y( 1, 3 ) ) {
3499 add_vehicle( vproto_id( "car" ), point( 17, 17 ), 180_degrees );
3500 }
3501 } else if( dat.east() == "office_tower_b" && dat.north() == "office_tower_b" ) {
3502 rotate( 2 );
3503 if( x_in_y( 1, 5 ) ) {
3504 if( one_in( 3 ) ) {
3505 add_vehicle( vproto_id( "cube_van" ), point( 6, 17 ), 270_degrees );
3506 } else {
3507 add_vehicle( vproto_id( "cube_van_cheap" ), point( 6, 17 ), 270_degrees );
3508 }
3509 }
3510 if( x_in_y( 1, 5 ) ) {
3511 add_vehicle( vproto_id( "pickup" ), point( 12, 17 ), 270_degrees );
3512 }
3513 if( x_in_y( 1, 3 ) ) {
3514 add_vehicle( vproto_id( "fire_truck" ), point( 18, 17 ), 270_degrees );
3515 }
3516 } else if( dat.east() == "office_tower_b" && dat.south() == "office_tower_b" ) {
3517 rotate( 3 );
3518 if( x_in_y( 1, 5 ) ) {
3519 add_vehicle( vproto_id( "cube_van_cheap" ), point( 6, 6 ), 0_degrees );
3520 }
3521 if( x_in_y( 1, 5 ) ) {
3522 if( one_in( 3 ) ) {
3523 add_vehicle( vproto_id( "fire_truck" ), point( 6, 13 ), 0_degrees );
3524 } else {
3525 add_vehicle( vproto_id( "pickup" ), point( 6, 13 ), 0_degrees );
3526 }
3527 }
3528 if( x_in_y( 1, 3 ) ) {
3529 add_vehicle( vproto_id( "car" ), point( 5, 19 ), 180_degrees );
3530 }
3531 } else {
3532 if( x_in_y( 1, 5 ) ) {
3533 add_vehicle( vproto_id( "flatbed_truck" ), point( 16, 6 ), 90_degrees );
3534 }
3535 if( x_in_y( 1, 5 ) ) {
3536 add_vehicle( vproto_id( "cube_van_cheap" ), point( 10, 6 ), 90_degrees );
3537 }
3538 if( x_in_y( 1, 3 ) ) {
3539 add_vehicle( vproto_id( "car" ), point( 4, 6 ), 90_degrees );
3540 }
3541 }
3542 }
3543 }
3544}
bool x_in_y(const time_duration &a, const time_duration &b)
Definition: calendar.cpp:521
void fill_groundcover()
Definition: mapgendata.cpp:125
float monster_density() const
Definition: mapgendata.h:90
furn_id f_chair
Definition: mapdata.cpp:1105
ter_id t_door_locked_alarm
Definition: mapdata.cpp:659
furn_id f_fridge
Definition: mapdata.cpp:1108
ter_id t_wall
Definition: mapdata.cpp:648
furn_id f_bookcase
Definition: mapdata.cpp:1109
ter_id t_pavement
Definition: mapdata.cpp:632
furn_id f_desk
Definition: mapdata.cpp:1105
ter_id t_railing
Definition: mapdata.cpp:690
furn_id f_indoor_plant
Definition: mapdata.cpp:1102
ter_id t_pavement_y
Definition: mapdata.cpp:632
ter_id t_wall_glass
Definition: mapdata.cpp:650
furn_id f_crate_c
Definition: mapdata.cpp:1112
furn_id f_toilet
Definition: mapdata.cpp:1103
ter_id t_window
Definition: mapdata.cpp:668
furn_id f_bench
Definition: mapdata.cpp:1106
ter_id t_door_glass_c
Definition: mapdata.cpp:666
ter_id t_console_broken
Definition: mapdata.cpp:706
ter_id t_door_locked
Definition: mapdata.cpp:659
furn_id f_locker
Definition: mapdata.cpp:1108
ter_id t_elevator
Definition: mapdata.cpp:725
furn_id f_sink
Definition: mapdata.cpp:1104
ter_id t_door_c
Definition: mapdata.cpp:658
static const mongroup_id GROUP_ZOMBIE_COP("GROUP_ZOMBIE_COP")
static const mongroup_id GROUP_PLAIN("GROUP_PLAIN")
static const mongroup_id GROUP_ZOMBIE("GROUP_ZOMBIE")
format_effect< furn_id > furn_bind(const char(&characters)[N], Args... ids)
Definition: mapgenformat.h:76
void formatted_set_simple(map *m, point start, const char *cstr, const format_effect< ter_id > &ter_b, const format_effect< furn_id > &furn_b)
Set terrain and furniture on the supplied map.
format_effect< ter_id > ter_bind(const char(&characters)[N], Args... ids)
The functions create a mapping of characters to ids, usable with formatted_set_simple.
Definition: mapgenformat.h:66
string_id< vehicle_prototype > vproto_id
Definition: type_id.h:196

References add_vehicle(), mapgendata::east(), EAST_EDGE, f_bench, f_bookcase, f_chair, f_counter, f_crate_c, f_desk, f_fridge, f_indoor_plant, f_locker, f_null, f_rack, f_sink, f_table, f_toilet, mapgendata::fill_groundcover(), mapf::formatted_set_simple(), mapf::furn_bind(), GROUP_PLAIN, GROUP_ZOMBIE, GROUP_ZOMBIE_COP, mapgendata::monster_density(), mapgendata::north(), one_in(), place_items(), place_spawns(), point_zero, rng(), rotate(), mapgendata::south(), SOUTH_EDGE, spawn_item(), calendar::start_of_cataclysm, t_console, t_console_broken, t_door_c, t_door_glass_c, t_door_locked, t_door_locked_alarm, t_door_metal_locked, t_elevator, t_floor, t_pavement, t_pavement_y, t_railing, t_rock, t_shrub, t_sidewalk, t_stairs_down, t_stairs_up, t_wall, t_wall_glass, t_window, mapf::ter_bind(), mapgendata::terrain_type(), mapgendata::west(), and x_in_y().

Referenced by draw_map().

◆ draw_rough_circle_furn()

void map::draw_rough_circle_furn ( const furn_id type,
point  p,
int  rad 
)

Definition at line 8492 of file map.cpp.

8493{
8494 draw_rough_circle( [this, type]( point q ) {
8495 this->furn_set( q, type );
8496 }, p, rad );
8497}

References draw_rough_circle(), furn_set(), rad, and type.

Referenced by rough_circle_furn().

◆ draw_rough_circle_ter()

void map::draw_rough_circle_ter ( const ter_id type,
point  p,
int  rad 
)

Definition at line 8485 of file map.cpp.

8486{
8487 draw_rough_circle( [this, type]( point q ) {
8488 this->ter_set( q, type );
8489 }, p, rad );
8490}

References draw_rough_circle(), rad, ter_set(), and type.

Referenced by rough_circle().

◆ draw_slimepit()

void map::draw_slimepit ( mapgendata dat)
protected

Definition at line 5081 of file mapgen.cpp.

5082{
5083 const oter_id &terrain_type = dat.terrain_type();
5084 if( is_ot_match( "slimepit", terrain_type, ot_match_type::prefix ) ) {
5085 for( int i = 0; i < SEEX * 2; i++ ) {
5086 for( int j = 0; j < SEEY * 2; j++ ) {
5087 if( !one_in( 10 ) && ( j < dat.n_fac * SEEX ||
5088 i < dat.w_fac * SEEX ||
5089 j > SEEY * 2 - dat.s_fac * SEEY ||
5090 i > SEEX * 2 - dat.e_fac * SEEX ) ) {
5091 ter_set( point( i, j ), ( !one_in( 10 ) ? t_slime : t_rock_floor ) );
5092 } else if( rng( 0, SEEX ) > std::abs( i - SEEX ) && rng( 0, SEEY ) > std::abs( j - SEEY ) ) {
5093 ter_set( point( i, j ), t_slime );
5094 } else if( dat.zlevel() == 0 ) {
5095 ter_set( point( i, j ), t_dirt );
5096 } else {
5097 ter_set( point( i, j ), t_rock_floor );
5098 }
5099 }
5100 }
5101 if( terrain_type == "slimepit_down" ) {
5102 ter_set( point( rng( 3, SEEX * 2 - 4 ), rng( 3, SEEY * 2 - 4 ) ), t_slope_down );
5103 }
5104 if( dat.above() == "slimepit_down" ) {
5105 switch( rng( 1, 4 ) ) {
5106 case 1:
5107 ter_set( point( rng( 0, 2 ), rng( 0, 2 ) ), t_slope_up );
5108 break;
5109 case 2:
5110 ter_set( point( rng( 0, 2 ), SEEY * 2 - rng( 1, 3 ) ), t_slope_up );
5111 break;
5112 case 3:
5113 ter_set( point( SEEX * 2 - rng( 1, 3 ), rng( 0, 2 ) ), t_slope_up );
5114 break;
5115 case 4:
5116 ter_set( point( SEEX * 2 - rng( 1, 3 ), SEEY * 2 - rng( 1, 3 ) ), t_slope_up );
5117 }
5118 }
5119 place_spawns( GROUP_BLOB, 1, point( SEEX, SEEY ), point( SEEX, SEEY ), 0.15 );
5120 place_items( item_group_id( "sewer" ), 40, point_zero, point( EAST_EDGE, SOUTH_EDGE ), true,
5122 }
5123}
static const mongroup_id GROUP_BLOB("GROUP_BLOB")

References mapgendata::above(), mapgendata::e_fac, EAST_EDGE, GROUP_BLOB, is_ot_match(), mapgendata::n_fac, one_in(), place_items(), place_spawns(), point_zero, prefix, rng(), mapgendata::s_fac, SEEX, SEEY, SOUTH_EDGE, calendar::start_of_cataclysm, t_dirt, t_rock_floor, t_slime, t_slope_down, t_slope_up, ter_set(), mapgendata::terrain_type(), mapgendata::w_fac, and mapgendata::zlevel().

Referenced by draw_map().

◆ draw_square_furn()

void map::draw_square_furn ( const furn_id type,
point  p1,
point  p2 
)

Definition at line 8462 of file map.cpp.

8463{
8464 draw_square( [this, type]( point p ) {
8465 this->furn_set( p, type );
8466 }, p1, p2 );
8467}
void draw_square(std::function< void(point)>set, point p1, point p2)

References draw_square(), furn_set(), and type.

Referenced by jmapgen_setmap::apply(), mission_start::ranch_nurse_1(), mission_start::ranch_nurse_2(), mission_start::ranch_nurse_7(), mission_start::ranch_nurse_8(), and square_furn().

◆ draw_square_ter() [1/3]

◆ draw_square_ter() [2/3]

void map::draw_square_ter ( const weighted_int_list< ter_id > &  f,
point  p1,
point  p2 
)

Definition at line 8476 of file map.cpp.

8478{
8479 draw_square( [this, f]( point p ) {
8480 const ter_id *tid = f.pick();
8481 this->ter_set( p, tid != nullptr ? *tid : t_null );
8482 }, p1, p2 );
8483}
ter_id t_null
Definition: mapdata.cpp:625
const T * pick(unsigned int randi) const
This will return a pointer to an object from the list randomly selected and biased by weight.
Definition: weighted_list.h:94

References draw_square(), weighted_list< W, T >::pick(), t_null, and ter_set().

◆ draw_square_ter() [3/3]

void map::draw_square_ter ( ter_id(*)()  f,
point  p1,
point  p2 
)

Definition at line 8469 of file map.cpp.

8470{
8471 draw_square( [this, f]( point p ) {
8472 this->ter_set( p, f() );
8473 }, p1, p2 );
8474}

References draw_square(), and ter_set().

◆ draw_temple()

void map::draw_temple ( mapgendata dat)
protected

Definition at line 4547 of file mapgen.cpp.

4548{
4549 const oter_id &terrain_type = dat.terrain_type();
4550 if( terrain_type == "temple" || terrain_type == "temple_stairs" ) {
4551 if( dat.zlevel() == 0 ) {
4552 // Ground floor
4553 // TODO: More varieties?
4554 fill_background( this, t_dirt );
4555 square( this, t_grate, point( SEEX - 1, SEEY - 1 ), point( SEEX, SEEX ) );
4556 ter_set( point( SEEX + 1, SEEY + 1 ), t_pedestal_temple );
4557 } else {
4558 // Underground! Shit's about to get interesting!
4559 // Start with all rock floor
4561 // We always start at the south and go north.
4562 // We use (y / 2 + z) % 4 to guarantee that rooms don't repeat.
4563 switch( 1 + std::abs( abs_sub.y / 2 + dat.zlevel() + 4 ) % 4 ) { // TODO: More varieties!
4564
4565 case 1:
4566 // Flame bursts
4567 square( this, t_rock, point_zero, point( SEEX - 1, SOUTH_EDGE ) );
4568 square( this, t_rock, point( SEEX + 2, 0 ), point( EAST_EDGE, SOUTH_EDGE ) );
4569 for( int i = 2; i < SEEY * 2 - 4; i++ ) {
4570 add_field( {SEEX, i, abs_sub.z}, fd_fire_vent, rng( 1, 3 ) );
4571 add_field( {SEEX + 1, i, abs_sub.z}, fd_fire_vent, rng( 1, 3 ) );
4572 }
4573 break;
4574
4575 case 2:
4576 // Spreading water
4577 square( this, t_water_dp, point( 4, 4 ), point( 5, 5 ) );
4578 // replaced mon_sewer_snake spawn with GROUP_SEWER
4579 // Decide whether a group of only sewer snakes be made, probably not worth it
4580 place_spawns( GROUP_SEWER, 1, point( 4, 4 ), point( 4, 4 ), 1, true );
4581
4582 square( this, t_water_dp, point( SEEX * 2 - 5, 4 ), point( SEEX * 2 - 4, 6 ) );
4583 place_spawns( GROUP_SEWER, 1, point( 1, SEEX * 2 - 5 ), point( 1, SEEX * 2 - 5 ), 1, true );
4584
4585 square( this, t_water_dp, point( 4, SEEY * 2 - 5 ), point( 6, SEEY * 2 - 4 ) );
4586
4587 square( this, t_water_dp, point( SEEX * 2 - 5, SEEY * 2 - 5 ), point( SEEX * 2 - 4,
4588 SEEY * 2 - 4 ) );
4589
4590 square( this, t_rock, point( 0, SEEY * 2 - 2 ), point( SEEX - 1, SOUTH_EDGE ) );
4591 square( this, t_rock, point( SEEX + 2, SEEY * 2 - 2 ), point( EAST_EDGE, SOUTH_EDGE ) );
4592 line( this, t_grate, point( SEEX, 1 ), point( SEEX + 1, 1 ) ); // To drain the water
4593 mtrap_set( this, point( SEEX, SEEY * 2 - 2 ), tr_temple_flood );
4594 mtrap_set( this, point( SEEX + 1, SEEY * 2 - 2 ), tr_temple_flood );
4595 for( int y = 2; y < SEEY * 2 - 2; y++ ) {
4596 for( int x = 2; x < SEEX * 2 - 2; x++ ) {
4597 if( ter( point( x, y ) ) == t_rock_floor && one_in( 4 ) ) {
4598 mtrap_set( this, point( x, y ), tr_temple_flood );
4599 }
4600 }
4601 }
4602 break;
4603
4604 case 3: { // Flipping walls puzzle
4605 line( this, t_rock, point_zero, point( SEEX - 1, 0 ) );
4606 line( this, t_rock, point( SEEX + 2, 0 ), point( EAST_EDGE, 0 ) );
4607 line( this, t_rock, point( SEEX - 1, 1 ), point( SEEX - 1, 6 ) );
4608 line( this, t_bars, point( SEEX + 2, 1 ), point( SEEX + 2, 6 ) );
4609 ter_set( point( 14, 1 ), t_switch_rg );
4610 ter_set( point( 15, 1 ), t_switch_gb );
4611 ter_set( point( 16, 1 ), t_switch_rb );
4612 ter_set( point( 17, 1 ), t_switch_even );
4613 // Start with clear floors--then work backwards to the starting state
4614 line( this, t_floor_red, point( SEEX, 1 ), point( SEEX + 1, 1 ) );
4615 line( this, t_floor_green, point( SEEX, 2 ), point( SEEX + 1, 2 ) );
4616 line( this, t_floor_blue, point( SEEX, 3 ), point( SEEX + 1, 3 ) );
4617 line( this, t_floor_red, point( SEEX, 4 ), point( SEEX + 1, 4 ) );
4618 line( this, t_floor_green, point( SEEX, 5 ), point( SEEX + 1, 5 ) );
4619 line( this, t_floor_blue, point( SEEX, 6 ), point( SEEX + 1, 6 ) );
4620 // Now, randomly choose actions
4621 // Set up an actions vector so that there's not undue repetition
4622 std::vector<int> actions;
4623 actions.push_back( 1 );
4624 actions.push_back( 2 );
4625 actions.push_back( 3 );
4626 actions.push_back( 4 );
4627 actions.push_back( rng( 1, 3 ) );
4628 while( !actions.empty() ) {
4629 const int action = random_entry_removed( actions );
4630 for( int y = 1; y < 7; y++ ) {
4631 for( int x = SEEX; x <= SEEX + 1; x++ ) {
4632 switch( action ) {
4633 case 1:
4634 // Toggle RG
4635 if( ter( point( x, y ) ) == t_floor_red ) {
4636 ter_set( point( x, y ), t_rock_red );
4637 } else if( ter( point( x, y ) ) == t_rock_red ) {
4638 ter_set( point( x, y ), t_floor_red );
4639 } else if( ter( point( x, y ) ) == t_floor_green ) {
4640 ter_set( point( x, y ), t_rock_green );
4641 } else if( ter( point( x, y ) ) == t_rock_green ) {
4642 ter_set( point( x, y ), t_floor_green );
4643 }
4644 break;
4645 case 2:
4646 // Toggle GB
4647 if( ter( point( x, y ) ) == t_floor_blue ) {
4648 ter_set( point( x, y ), t_rock_blue );
4649 } else if( ter( point( x, y ) ) == t_rock_blue ) {
4650 ter_set( point( x, y ), t_floor_blue );
4651 } else if( ter( point( x, y ) ) == t_floor_green ) {
4652 ter_set( point( x, y ), t_rock_green );
4653 } else if( ter( point( x, y ) ) == t_rock_green ) {
4654 ter_set( point( x, y ), t_floor_green );
4655 }
4656 break;
4657 case 3:
4658 // Toggle RB
4659 if( ter( point( x, y ) ) == t_floor_blue ) {
4660 ter_set( point( x, y ), t_rock_blue );
4661 } else if( ter( point( x, y ) ) == t_rock_blue ) {
4662 ter_set( point( x, y ), t_floor_blue );
4663 } else if( ter( point( x, y ) ) == t_floor_red ) {
4664 ter_set( point( x, y ), t_rock_red );
4665 } else if( ter( point( x, y ) ) == t_rock_red ) {
4666 ter_set( point( x, y ), t_floor_red );
4667 }
4668 break;
4669 case 4:
4670 // Toggle Even
4671 if( y % 2 == 0 ) {
4672 if( ter( point( x, y ) ) == t_floor_blue ) {
4673 ter_set( point( x, y ), t_rock_blue );
4674 } else if( ter( point( x, y ) ) == t_rock_blue ) {
4675 ter_set( point( x, y ), t_floor_blue );
4676 } else if( ter( point( x, y ) ) == t_floor_red ) {
4677 ter_set( point( x, y ), t_rock_red );
4678 } else if( ter( point( x, y ) ) == t_rock_red ) {
4679 ter_set( point( x, y ), t_floor_red );
4680 } else if( ter( point( x, y ) ) == t_floor_green ) {
4681 ter_set( point( x, y ), t_rock_green );
4682 } else if( ter( point( x, y ) ) == t_rock_green ) {
4683 ter_set( point( x, y ), t_floor_green );
4684 }
4685 }
4686 break;
4687 }
4688 }
4689 }
4690 }
4691 }
4692 break;
4693
4694 case 4: { // Toggling walls maze
4695 square( this, t_rock, point_zero, point( SEEX - 1, 1 ) );
4696 square( this, t_rock, point( 0, SEEY * 2 - 2 ), point( SEEX - 1, SOUTH_EDGE ) );
4697 square( this, t_rock, point( 0, 2 ), point( SEEX - 4, SEEY * 2 - 3 ) );
4698 square( this, t_rock, point( SEEX + 2, 0 ), point( EAST_EDGE, 1 ) );
4699 square( this, t_rock, point( SEEX + 2, SEEY * 2 - 2 ), point( EAST_EDGE, SOUTH_EDGE ) );
4700 square( this, t_rock, point( SEEX + 5, 2 ), point( EAST_EDGE, SEEY * 2 - 3 ) );
4701 int x = rng( SEEX - 1, SEEX + 2 ), y = 2;
4702 std::vector<point> path; // Path, from end to start
4703 while( x < SEEX - 1 || x > SEEX + 2 || y < SEEY * 2 - 2 ) {
4704 static const std::vector<ter_id> terrains = {
4706 };
4707 path.push_back( point( x, y ) );
4708 ter_set( point( x, y ), random_entry( terrains ) );
4709 if( y == SEEY * 2 - 2 ) {
4710 if( x < SEEX - 1 ) {
4711 x++;
4712 } else if( x > SEEX + 2 ) {
4713 x--;
4714 }
4715 } else {
4716 std::vector<point> next;
4717 for( int nx = x - 1; nx <= x + 1; nx++ ) {
4718 for( int ny = y; ny <= y + 1; ny++ ) {
4719 if( ter( point( nx, ny ) ) == t_rock_floor ) {
4720 next.push_back( point( nx, ny ) );
4721 }
4722 }
4723 }
4724 if( next.empty() ) {
4725 break;
4726 } else {
4727 const point p = random_entry( next );
4728 x = p.x;
4729 y = p.y;
4730 }
4731 }
4732 }
4733 // Now go backwards through path (start to finish), toggling any tiles that need
4734 bool toggle_red = false;
4735 bool toggle_green = false;
4736 bool toggle_blue = false;
4737 for( int i = path.size() - 1; i >= 0; i-- ) {
4738 if( ter( path[i] ) == t_floor_red ) {
4739 toggle_green = !toggle_green;
4740 if( toggle_red ) {
4741 ter_set( path[i], t_rock_red );
4742 }
4743 } else if( ter( path[i] ) == t_floor_green ) {
4744 toggle_blue = !toggle_blue;
4745 if( toggle_green ) {
4746 ter_set( path[i], t_rock_green );
4747 }
4748 } else if( ter( path[i] ) == t_floor_blue ) {
4749 toggle_red = !toggle_red;
4750 if( toggle_blue ) {
4751 ter_set( path[i], t_rock_blue );
4752 }
4753 }
4754 }
4755 // Finally, fill in the rest with random tiles, and place toggle traps
4756 for( int i = SEEX - 3; i <= SEEX + 4; i++ ) {
4757 for( int j = 2; j <= SEEY * 2 - 2; j++ ) {
4758 mtrap_set( this, point( i, j ), tr_temple_toggle );
4759 if( ter( point( i, j ) ) == t_rock_floor ) {
4760 static const std::vector<ter_id> terrains = {
4763 };
4764 ter_set( point( i, j ), random_entry( terrains ) );
4765 }
4766 }
4767 }
4768 }
4769 break;
4770 } // Done with room type switch
4771 // Stairs down if we need them
4772 if( terrain_type == "temple_stairs" ) {
4773 line( this, t_stairs_down, point( SEEX, 0 ), point( SEEX + 1, 0 ) );
4774 }
4775 // Stairs at the south if dat.above() has stairs down.
4776 if( dat.above() == "temple_stairs" ) {
4777 line( this, t_stairs_up, point( SEEX, SOUTH_EDGE ), point( SEEX + 1, SOUTH_EDGE ) );
4778 }
4779
4780 } // Done with underground-only stuff
4781 } else if( terrain_type == "temple_finale" ) {
4782 fill_background( this, t_rock );
4783 square( this, t_rock_floor, point( SEEX - 1, 1 ), point( SEEX + 2, 4 ) );
4784 square( this, t_rock_floor, point( SEEX, 5 ), point( SEEX + 1, SOUTH_EDGE ) );
4785 line( this, t_stairs_up, point( SEEX, SOUTH_EDGE ), point( SEEX + 1, SOUTH_EDGE ) );
4786 spawn_artifact( tripoint( rng( SEEX, SEEX + 1 ), rng( 2, 3 ), abs_sub.z ) );
4787 spawn_artifact( tripoint( rng( SEEX, SEEX + 1 ), rng( 2, 3 ), abs_sub.z ) );
4788 return;
4789
4790 }
4791}
@ action
Definition: dialogue.h:36
ter_id t_switch_even
Definition: mapdata.cpp:729
ter_id t_rock_red
Definition: mapdata.cpp:728
ter_id t_pedestal_temple
Definition: mapdata.cpp:726
ter_id t_floor_blue
Definition: mapdata.cpp:728
ter_id t_grate
Definition: mapdata.cpp:638
ter_id t_switch_rb
Definition: mapdata.cpp:729
ter_id t_rock_green
Definition: mapdata.cpp:728
ter_id t_rock_blue
Definition: mapdata.cpp:728
ter_id t_floor_green
Definition: mapdata.cpp:728
ter_id t_switch_gb
Definition: mapdata.cpp:729
ter_id t_floor_red
Definition: mapdata.cpp:728
ter_id t_switch_rg
Definition: mapdata.cpp:729
static const mongroup_id GROUP_SEWER("GROUP_SEWER")
static const trap_str_id tr_temple_flood("tr_temple_flood")
generic_factory< oter_t > terrains("overmap terrain")
V random_entry_removed(C &container)
Returns a random entry in the container and removes it from the container.
Definition: rng.h:170
trap_id tr_temple_toggle
Definition: trap.cpp:311

References mapgendata::above(), abs_sub, action, add_field(), EAST_EDGE, fd_fire_vent, fill_background(), GROUP_SEWER, line(), mtrap_set(), one_in(), place_spawns(), point_zero, random_entry(), random_entry_removed(), rng(), SEEX, SEEY, SOUTH_EDGE, spawn_artifact(), square(), t_bars, t_dirt, t_floor_blue, t_floor_green, t_floor_red, t_grate, t_pedestal_temple, t_rock, t_rock_blue, t_rock_floor, t_rock_green, t_rock_red, t_stairs_down, t_stairs_up, t_switch_even, t_switch_gb, t_switch_rb, t_switch_rg, t_water_dp, ter(), ter_set(), mapgendata::terrain_type(), anonymous_namespace{overmap.cpp}::terrains, tr_temple_flood, tr_temple_toggle, point::x, point::y, tripoint::y, tripoint::z, and mapgendata::zlevel().

Referenced by draw_map().

◆ draw_triffid()

void map::draw_triffid ( mapgendata dat)
protected

Definition at line 5125 of file mapgen.cpp.

5126{
5127 const oter_id &terrain_type = dat.terrain_type();
5128 if( terrain_type == "triffid_roots" ) {
5130 int node = 0;
5131 int step = 0;
5132 bool node_built[16];
5133 bool done = false;
5134 for( auto &elem : node_built ) {
5135 elem = false;
5136 }
5137 do {
5138 node_built[node] = true;
5139 step++;
5140 point node2( 1 + 6 * ( node % 4 ), 1 + 6 * static_cast<int>( node / 4 ) );
5141 // Clear a 4x4 dirt square
5142 square( this, t_dirt, node2, node2 + point( 3, 3 ) );
5143 // Spawn a monster in there
5144 if( step > 2 ) { // First couple of chambers are safe
5145 int monrng = rng( 1, 25 );
5146 point spawn( node2 + point{ rng( 0, 3 ), rng( 0, 3 ) } );
5147 if( monrng <= 24 ) {
5149 node2 + point( 3, 3 ), 1, true );
5150 } else {
5151 for( int webx = node2.x; webx <= node2.x + 3; webx++ ) {
5152 for( int weby = node2.y; weby <= node2.y + 3; weby++ ) {
5153 add_field( {webx, weby, abs_sub.z}, fd_web, rng( 1, 3 ) );
5154 }
5155 }
5156 place_spawns( GROUP_SPIDER, 1, spawn, spawn, 1, true );
5157 }
5158 }
5159 // TODO: Non-monster hazards?
5160 // Next, pick a cell to move to
5161 std::vector<direction> move;
5162 if( node % 4 > 0 && !node_built[node - 1] ) {
5163 move.push_back( direction::WEST );
5164 }
5165 if( node % 4 < 3 && !node_built[node + 1] ) {
5166 move.push_back( direction::EAST );
5167 }
5168 if( static_cast<int>( node / 4 ) > 0 && !node_built[node - 4] ) {
5169 move.push_back( direction::NORTH );
5170 }
5171 if( static_cast<int>( node / 4 ) < 3 && !node_built[node + 4] ) {
5172 move.push_back( direction::SOUTH );
5173 }
5174
5175 if( move.empty() ) { // Nowhere to go!
5176 square( this, t_slope_down, node2 + point_south_east, node2 + point( 2, 2 ) );
5177 done = true;
5178 } else {
5179 switch( random_entry( move ) ) {
5180 case direction::NORTH:
5181 square( this, t_dirt, node2 + point( 1, -2 ), node2 + point( 2, -1 ) );
5182 node -= 4;
5183 break;
5184 case direction::EAST:
5185 square( this, t_dirt, node2 + point( 4, 1 ), node2 + point( 5, 2 ) );
5186 node++;
5187 break;
5188 case direction::SOUTH:
5189 square( this, t_dirt, node2 + point( 1, 4 ), node2 + point( 2, 5 ) );
5190 node += 4;
5191 break;
5192 case direction::WEST:
5193 square( this, t_dirt, node2 + point( -2, 1 ), node2 + point( -1, 2 ) );
5194 node--;
5195 break;
5196 default:
5197 break;
5198 }
5199 }
5200 } while( !done );
5201 square( this, t_slope_up, point( 2, 2 ), point( 3, 3 ) );
5202 rotate( rng( 0, 3 ) );
5203 } else if( terrain_type == "triffid_finale" ) {
5205 // NOLINTNEXTLINE(cata-use-named-point-constants)
5206 square( this, t_dirt, point( 1, 1 ), point( 4, 4 ) );
5207 square( this, t_dirt, point( 19, 19 ), point( 22, 22 ) );
5208 // Drunken walk until we reach the heart (lower right, [19, 19])
5209 // Chance increases by 1 each turn, and gives the % chance of forcing a move
5210 // to the right or down.
5211 int chance = 0;
5212 int x = 4;
5213 int y = 4;
5214 do {
5215 ter_set( point( x, y ), t_dirt );
5216
5217 if( chance >= 10 && one_in( 10 ) ) { // Add a spawn
5218 place_spawns( GROUP_TRIFFID, 1, point( x, y ), point( x, y ), 1, true );
5219 }
5220
5221 if( rng( 0, 99 ) < chance ) { // Force movement down or to the right
5222 if( x >= 19 ) {
5223 y++;
5224 } else if( y >= 19 ) {
5225 x++;
5226 } else {
5227 if( one_in( 2 ) ) {
5228 x++;
5229 } else {
5230 y++;
5231 }
5232 }
5233 } else {
5234 chance++; // Increase chance of forced movement down/right
5235 // Weigh movement towards directions with lots of existing walls
5236 int chance_west = 0;
5237 int chance_east = 0;
5238 int chance_north = 0;
5239 int chance_south = 0;
5240 for( int dist = 1; dist <= 5; dist++ ) {
5241 if( ter( point( x - dist, y ) ) == t_root_wall ) {
5242 chance_west++;
5243 }
5244 if( ter( point( x + dist, y ) ) == t_root_wall ) {
5245 chance_east++;
5246 }
5247 if( ter( point( x, y - dist ) ) == t_root_wall ) {
5248 chance_north++;
5249 }
5250 if( ter( point( x, y + dist ) ) == t_root_wall ) {
5251 chance_south++;
5252 }
5253 }
5254 int roll = rng( 0, chance_west + chance_east + chance_north + chance_south );
5255 if( roll < chance_west && x > 0 ) {
5256 x--;
5257 } else if( roll < chance_west + chance_east && x < EAST_EDGE ) {
5258 x++;
5259 } else if( roll < chance_west + chance_east + chance_north && y > 0 ) {
5260 y--;
5261 } else if( y < SOUTH_EDGE ) {
5262 y++;
5263 }
5264 } // Done with drunken walk
5265 } while( x < 19 || y < 19 );
5266 // NOLINTNEXTLINE(cata-use-named-point-constants)
5267 square( this, t_slope_up, point( 1, 1 ), point( 2, 2 ) );
5268 place_spawns( GROUP_TRIFFID_HEART, 1, point( 21, 21 ), point( 21, 21 ), 1, true );
5269
5270 }
5271}
ter_id t_root_wall
Definition: mapdata.cpp:686
static const mongroup_id GROUP_TRIFFID_OUTER("GROUP_TRIFFID_OUTER")
static const mongroup_id GROUP_SPIDER("GROUP_SPIDER")
static const mongroup_id GROUP_TRIFFID("GROUP_TRIFFID")
static const mongroup_id GROUP_TRIFFID_HEART("GROUP_TRIFFID_HEART")

References abs_sub, add_field(), detail::digits::done, EAST, EAST_EDGE, fd_web, fill_background(), GROUP_SPIDER, GROUP_TRIFFID, GROUP_TRIFFID_HEART, GROUP_TRIFFID_OUTER, avatar_action::move(), NORTH, one_in(), place_spawns(), point_south_east, random_entry(), rng(), rotate(), SOUTH, SOUTH_EDGE, square(), t_dirt, t_root_wall, t_slope_down, t_slope_up, ter(), ter_set(), mapgendata::terrain_type(), WEST, point::x, point::y, and tripoint::z.

Referenced by draw_map().

◆ drawsq()

void map::drawsq ( const catacurses::window w,
const tripoint p,
const drawsq_params params 
) const

Draw the map tile at the given coordinate.

Called by map::draw().

Parameters
wThe window we are drawing in
pThe tile on this map to draw.
paramsDraw parameters.

Definition at line 5901 of file map.cpp.

5903{
5904 // If we are in tiles mode, the only thing we want to potentially draw is a highlight
5905 if( is_draw_tiles_mode() ) {
5906 if( params.highlight() ) {
5907 g->draw_highlight( p );
5908 }
5909 return;
5910 }
5911
5912 if( !inbounds( p ) ) {
5913 return;
5914 }
5915
5916 const tripoint view_center = params.center();
5917 const int k = p.x + getmaxx( w ) / 2 - view_center.x;
5918 const int j = p.y + getmaxy( w ) / 2 - view_center.y;
5919 wmove( w, point( k, j ) );
5920
5921 const maptile tile = maptile_at( p );
5922 if( draw_maptile( w, p, tile, params ) ) {
5923 return;
5924 }
5925
5926 tripoint below( p.xy(), p.z - 1 );
5927 const maptile tile_below = maptile_at( below );
5928 draw_from_above( w, below, tile_below, params );
5929}
maptile maptile_at(const tripoint &p) const
Definition: map.cpp:259
constexpr drawsq_params & center(const tripoint &p)
Set view center.
Definition: map.h:283

References drawsq_params::center(), draw_from_above(), draw_maptile(), g, catacurses::getmaxx(), catacurses::getmaxy(), drawsq_params::highlight(), inbounds(), is_draw_tiles_mode(), maptile_at(), catacurses::wmove(), tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by choose_adjacent_highlight(), anonymous_namespace{animation.cpp}::draw_line_curses(), game::draw_look_around_cursor(), editmap::draw_main_ui_overlay(), target_ui::draw_terrain_overlay(), game::pickup(), place_construction(), and editmap::uber_draw_ter().

◆ drop_everything()

void map::drop_everything ( const tripoint p)

Handles map objects of given type (not creatures) falling down.

Returns true if anything changed.

Definition at line 2103 of file map.cpp.

2104{
2105 //Do a suspension check so that there won't be a floor there for the rest of this check.
2106 if( has_flag( "SUSPENDED", p ) ) {
2108 }
2109 if( has_floor( p ) ) {
2110 return;
2111 }
2112
2113 drop_furniture( p );
2114 drop_items( p );
2115 drop_vehicle( p );
2116 drop_fields( p );
2117}
void drop_furniture(const tripoint &p)
Definition: map.cpp:2119
void drop_items(const tripoint &p)
Definition: map.cpp:2261
void drop_vehicle(const tripoint &p)
Definition: map.cpp:2291
void collapse_invalid_suspension(const tripoint &point)
Triggers a recursive collapse of suspended tiles based on their support validity.
Definition: map.cpp:3021
void drop_fields(const tripoint &p)
Definition: map.cpp:2301
bool has_floor(const tripoint &p) const
Definition: map.cpp:2065

References collapse_invalid_suspension(), drop_fields(), drop_furniture(), drop_items(), drop_vehicle(), has_flag(), and has_floor().

Referenced by process_falling().

◆ drop_fields()

void map::drop_fields ( const tripoint p)

Definition at line 2301 of file map.cpp.

2302{
2303 field &fld = field_at( p );
2304 if( fld.field_count() == 0 ) {
2305 return;
2306 }
2307
2308 std::list<field_type_id> dropped;
2309 const tripoint below = p + tripoint_below;
2310 for( const auto &iter : fld ) {
2311 const field_entry &entry = iter.second;
2312 // For now only drop cosmetic fields, which don't warrant per-turn check
2313 // Active fields "drop themselves"
2314 if( entry.decays_on_actualize() ) {
2315 add_field( below, entry.get_field_type(), entry.get_field_intensity(), entry.get_field_age() );
2316 dropped.push_back( entry.get_field_type() );
2317 }
2318 }
2319
2320 for( const auto &entry : dropped ) {
2321 fld.remove_field( entry );
2322 }
2323}
bool decays_on_actualize() const
Definition: field.h:105

References add_field(), field_entry::decays_on_actualize(), field_at(), field::field_count(), field_entry::get_field_age(), field_entry::get_field_intensity(), field_entry::get_field_type(), field::remove_field(), and tripoint_below.

Referenced by drop_everything().

◆ drop_furniture()

void map::drop_furniture ( const tripoint p)

Definition at line 2119 of file map.cpp.

2120{
2121 const furn_id frn = furn( p );
2122 if( frn == f_null ) {
2123 return;
2124 }
2125
2126 enum support_state {
2127 SS_NO_SUPPORT = 0,
2128 SS_BAD_SUPPORT, // TODO: Implement bad, shaky support
2129 SS_GOOD_SUPPORT,
2130 SS_FLOOR, // Like good support, but bash floor instead of tile below
2131 SS_CREATURE
2132 };
2133
2134 // Checks if the tile:
2135 // has floor (supports unconditionally)
2136 // has support below
2137 // has unsupporting furniture below (bad support, things should "slide" if possible)
2138 // has no support and thus allows things to fall through
2139 const auto check_tile = [this]( const tripoint & pt ) {
2140 if( has_floor( pt ) ) {
2141 return SS_FLOOR;
2142 }
2143
2144 tripoint below_dest( pt.xy(), pt.z - 1 );
2145 if( supports_above( below_dest ) ) {
2146 return SS_GOOD_SUPPORT;
2147 }
2148
2149 const furn_id frn_id = furn( below_dest );
2150 if( frn_id != f_null ) {
2151 const furn_t &frn = frn_id.obj();
2152 // Allow crushing tiny/nocollide furniture
2153 if( !frn.has_flag( "TINY" ) && !frn.has_flag( "NOCOLLIDE" ) ) {
2154 return SS_BAD_SUPPORT;
2155 }
2156 }
2157
2158 if( g->critter_at( below_dest ) != nullptr ) {
2159 // Smash a critter
2160 return SS_CREATURE;
2161 }
2162
2163 return SS_NO_SUPPORT;
2164 };
2165
2166 tripoint current( p.xy(), p.z + 1 );
2167 support_state last_state = SS_NO_SUPPORT;
2168 while( last_state == SS_NO_SUPPORT ) {
2169 current.z--;
2170 // Check current tile
2171 last_state = check_tile( current );
2172 }
2173
2174 if( current == p ) {
2175 // Nothing happened
2176 if( last_state != SS_FLOOR ) {
2177 support_dirty( current );
2178 }
2179
2180 return;
2181 }
2182
2183 furn_set( p, f_null );
2184 furn_set( current, frn );
2185
2186 // If it's sealed, we need to drop items with it
2187 const auto &frn_obj = frn.obj();
2188 if( frn_obj.has_flag( TFLAG_SEALED ) && has_items( p ) ) {
2189 auto old_items = i_at( p );
2190 auto new_items = i_at( current );
2191 for( const auto &it : old_items ) {
2192 new_items.insert( it );
2193 }
2194
2195 i_clear( p );
2196 }
2197
2198 // Approximate weight/"bulkiness" based on strength to drag
2199 int weight;
2200 if( frn_obj.has_flag( "TINY" ) || frn_obj.has_flag( "NOCOLLIDE" ) ) {
2201 weight = 5;
2202 } else {
2203 weight = frn_obj.is_movable() ? frn_obj.move_str_req : 20;
2204 }
2205
2206 if( frn_obj.has_flag( "ROUGH" ) || frn_obj.has_flag( "SHARP" ) ) {
2207 weight += 5;
2208 }
2209
2210 // TODO: Balance this.
2211 int dmg = weight * ( p.z - current.z );
2212
2213 if( last_state == SS_FLOOR ) {
2214 // Bash the same tile twice - once for furniture, once for the floor
2215 bash( current, dmg, false, false, true );
2216 bash( current, dmg, false, false, true );
2217 } else if( last_state == SS_BAD_SUPPORT || last_state == SS_GOOD_SUPPORT ) {
2218 bash( current, dmg, false, false, false );
2219 tripoint below( current.xy(), current.z - 1 );
2220 bash( below, dmg, false, false, false );
2221 } else if( last_state == SS_CREATURE ) {
2222 const std::string &furn_name = frn_obj.name();
2223 bash( current, dmg, false, false, false );
2224 tripoint below( current.xy(), current.z - 1 );
2225 Creature *critter = g->critter_at( below );
2226 if( critter == nullptr ) {
2227 debugmsg( "drop_furniture couldn't find creature at %d,%d,%d",
2228 below.x, below.y, below.z );
2229 return;
2230 }
2231
2232 critter->add_msg_player_or_npc( m_bad, _( "Falling %s hits you!" ),
2233 _( "Falling %s hits <npcname>" ),
2234 furn_name );
2235 // TODO: A chance to dodge/uncanny dodge
2236 player *pl = dynamic_cast<player *>( critter );
2237 monster *mon = dynamic_cast<monster *>( critter );
2238 if( pl != nullptr ) {
2239 pl->deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_BASH, rng( dmg / 3, dmg ), 0,
2240 0.5f ) );
2241 pl->deal_damage( nullptr, bodypart_id( "head" ), damage_instance( DT_BASH, rng( dmg / 3, dmg ), 0,
2242 0.5f ) );
2243 pl->deal_damage( nullptr, bodypart_id( "leg_l" ), damage_instance( DT_BASH, rng( dmg / 2, dmg ), 0,
2244 0.4f ) );
2245 pl->deal_damage( nullptr, bodypart_id( "leg_r" ), damage_instance( DT_BASH, rng( dmg / 2, dmg ), 0,
2246 0.4f ) );
2247 pl->deal_damage( nullptr, bodypart_id( "arm_l" ), damage_instance( DT_BASH, rng( dmg / 2, dmg ), 0,
2248 0.4f ) );
2249 pl->deal_damage( nullptr, bodypart_id( "arm_r" ), damage_instance( DT_BASH, rng( dmg / 2, dmg ), 0,
2250 0.4f ) );
2251 } else if( mon != nullptr ) {
2252 // TODO: Monster's armor and size - don't crush hulks with chairs
2253 mon->apply_damage( nullptr, bodypart_id( "torso" ), rng( dmg, dmg * 2 ) );
2254 }
2255 }
2256
2257 // Re-queue for another check, in case bash destroyed something
2258 support_dirty( current );
2259}
bool supports_above(const tripoint &p) const
Does this tile support vehicles and furniture above it.
Definition: map.cpp:2078
void apply_damage(Creature *source, bodypart_id bp, int dam, bool bypass_med=false) override
Definition: monster.cpp:1669

References _, Creature::add_msg_player_or_npc(), monster::apply_damage(), bash(), Character::deal_damage(), debugmsg, DT_BASH, f_null, furn(), furn_set(), g, map_data_common_t::has_flag(), has_floor(), has_items(), i_at(), i_clear(), m_bad, int_id< T >::obj(), rng(), support_dirty(), supports_above(), TFLAG_SEALED, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by drop_everything().

◆ drop_items()

void map::drop_items ( const tripoint p)

Definition at line 2261 of file map.cpp.

2262{
2263 if( !has_items( p ) ) {
2264 return;
2265 }
2266
2267 auto items = i_at( p );
2268 // TODO: Make items check the volume tile below can accept
2269 // rather than disappearing if it would be overloaded
2270
2271 tripoint below( p );
2272 while( !has_floor( below ) ) {
2273 below.z--;
2274 }
2275
2276 if( below == p ) {
2277 return;
2278 }
2279
2280 for( const auto &i : items ) {
2281 // TODO: Bash the item up before adding it
2282 // TODO: Bash the creature, terrain, furniture and vehicles on the tile
2283 add_item_or_charges( below, i );
2284 }
2285
2286 // Just to make a sound for now
2287 bash( below, 1 );
2288 i_clear( p );
2289}

References add_item_or_charges(), bash(), has_floor(), has_items(), i_at(), i_clear(), and tripoint::z.

Referenced by drop_everything().

◆ drop_vehicle()

void map::drop_vehicle ( const tripoint p)

Definition at line 2291 of file map.cpp.

2292{
2293 const optional_vpart_position vp = veh_at( p );
2294 if( !vp ) {
2295 return;
2296 }
2297
2298 vp->vehicle().is_falling = true;
2299}

References veh_at().

Referenced by drop_everything().

◆ emit_field()

void map::emit_field ( const tripoint pos,
const emit_id src,
float  mul = 1.0f 
)

Runs one cycle of emission src which may result in propagation of fields.

Parameters
posLocation of emission
srcId of object producing the emission
mulMultiplies the chance and possibly qty (if chance*mul > 100) of the emission

Definition at line 1928 of file map_field.cpp.

1929{
1930 if( !src.is_valid() ) {
1931 return;
1932 }
1933
1934 const float chance = src->chance() * mul;
1935 if( src.is_valid() && x_in_y( chance, 100 ) ) {
1936 const int qty = chance > 100.0f ? roll_remainder( src->qty() * chance / 100.0f ) : src->qty();
1937 propagate_field( pos, src->field(), qty, src->intensity() );
1938 }
1939}
int intensity() const
Intensity of output fields, range [1..maximum_intensity].
Definition: emit.h:34
int qty() const
Units of field to generate per turn subject to chance.
Definition: emit.h:39
int chance() const
Chance to emit each turn, range [1..100].
Definition: emit.h:44
field_type_id field() const
Type of field to emit.
Definition: emit.h:29
void propagate_field(const tripoint &center, const field_type_id &type, int amount, int max_intensity=0)
Definition: map_field.cpp:1941
bool is_valid() const
Returns whether this id is valid, that means whether it refers to an existing object.
Definition: achievement.cpp:65
int roll_remainder(double value)
Definition: rng.cpp:96

References emit::chance(), emit::field(), emit::intensity(), string_id< T >::is_valid(), propagate_field(), emit::qty(), roll_remainder(), and x_in_y().

Referenced by enchantment::activate_passive(), Character::burn_fuel(), game::do_turn(), Character::heat_emission(), Character::passive_power_gen(), item::process_internal(), projectile_attack(), and emit_actor::use().

◆ examine()

void map::examine ( Character p,
const tripoint pos 
)

Calls the examine function of furniture or terrain at given tile, for given character.

Examines the tile pos, with character as the "examinator" Casts Character to player because player/NPC split isn't done yet.

Will only examine terrain if furniture had iexamine::none as the examine function.

Definition at line 1678 of file map.cpp.

1679{
1680 const auto furn_here = furn( pos ).obj();
1681 if( furn_here.examine != iexamine::none ) {
1682 furn_here.examine( dynamic_cast<player &>( p ), pos );
1683 } else {
1684 ter( pos ).obj().examine( dynamic_cast<player &>( p ), pos );
1685 }
1686}
void none(player &p, const tripoint &examp)
Nothing player can interact with here.
Definition: iexamine.cpp:252
iexamine_function examine
Definition: mapdata.h:402

References map_data_common_t::examine, furn(), iexamine::none(), int_id< T >::obj(), wrapped_vehicle::pos, and ter().

Referenced by npc::pick_up_item(), and water_from().

◆ features() [1/2]

std::string map::features ( const tripoint p)

Definition at line 1772 of file map.cpp.

1773{
1774 std::string result;
1775 const auto add = [&]( const std::string & text ) {
1776 if( !result.empty() ) {
1777 result += " ";
1778 }
1779 result += text;
1780 };
1781 const auto add_if = [&]( const bool cond, const std::string & text ) {
1782 if( cond ) {
1783 add( text );
1784 }
1785 };
1786 // This is used in an info window that is 46 characters wide, and is expected
1787 // to take up one line. So, make sure it does that.
1788 // FIXME: can't control length of localized text.
1789 add_if( is_bashable( p ), _( "Smashable." ) );
1790 add_if( has_flag( "DIGGABLE", p ), _( "Diggable." ) );
1791 add_if( has_flag( "PLOWABLE", p ), _( "Plowable." ) );
1792 add_if( has_flag( "ROUGH", p ), _( "Rough." ) );
1793 add_if( has_flag( "UNSTABLE", p ), _( "Unstable." ) );
1794 add_if( has_flag( "SHARP", p ), _( "Sharp." ) );
1795 add_if( has_flag( "FLAT", p ), _( "Flat." ) );
1796 add_if( has_flag( "EASY_DECONSTRUCT", p ), _( "Simple." ) );
1797 add_if( has_flag( "MOUNTABLE", p ), _( "Mountable." ) );
1798 return result;
1799}
bool is_bashable(const tripoint &p, bool allow_floor=false) const
Returns true if there is a bashable vehicle part or the furn/terrain is bashable at p.
Definition: map.cpp:2483
type add(type dir1, type dir2)
Returns a sum of two numbers.
Definition: overmap.cpp:4193

References _, om_direction::add(), has_flag(), and is_bashable().

Referenced by features(), game::print_terrain_info(), and editmap::update_view_with_help().

◆ features() [2/2]

std::string map::features ( point  p)
inline

Definition at line 898 of file map.h.

898 {
899 return features( tripoint( p, abs_sub.z ) );
900 }
std::string features(const tripoint &p)
Definition: map.cpp:1772

References abs_sub, features(), and tripoint::z.

◆ field_at() [1/2]

field & map::field_at ( const tripoint p)

Gets fields that are here.

Both for querying and edition.

Definition at line 5376 of file map.cpp.

5377{
5378 if( !inbounds( p ) ) {
5379 nulfield = field();
5380 return nulfield;
5381 }
5382
5383 point l;
5384 submap *const current_submap = get_submap_at( p, l );
5385
5386 return current_submap->get_field( l );
5387}
static field nulfield
Definition: map.cpp:141
@ field
Consumes field to recharge.

References field, submap::get_field(), get_submap_at(), inbounds(), and nulfield.

◆ field_at() [2/2]

const field & map::field_at ( const tripoint p) const

Get the fields that are here.

This is for querying and looking at it only, one can not change the fields.

Parameters
pThe local map coordinates, if out of bounds, returns an empty field.

Definition at line 5360 of file map.cpp.

5361{
5362 if( !inbounds( p ) ) {
5363 nulfield = field();
5364 return nulfield;
5365 }
5366
5367 point l;
5368 submap *const current_submap = get_submap_at( p, l );
5369
5370 return current_submap->get_field( l );
5371}

References field, submap::get_field(), get_submap_at(), inbounds(), and nulfield.

Referenced by npc::could_move_onto(), dangerous_field_at(), decay_cosmetic_fields(), character_funcs::do_pause(), editmap_hilight::draw(), editmap::draw_main_ui_overlay(), drop_fields(), get_convection_temperature(), game::get_dangerous_tile(), get_field(), get_field_age(), get_field_intensity(), npc::good_escape_direction(), advanced_inv_area::init(), mop_spills(), character_funcs::pick_safe_adjacent_tile(), game::print_fields_info(), process_fields_in_submap(), relic_funcs::process_recharge_entry(), smash(), spell_move(), and Character::symbol_color().

◆ fill_funnels()

void map::fill_funnels ( const tripoint p,
const time_point since 
)
protected

Try to fill funnel based items here.

Simulates rain from since till now.

Parameters
pThe location in this map where to fill funnels.

Definition at line 7202 of file map.cpp.

7203{
7204 const auto &tr = tr_at( p );
7205 if( !tr.is_funnel() ) {
7206 return;
7207 }
7208 // Note: the inside/outside cache might not be correct at this time
7210 return;
7211 }
7212 auto items = i_at( p );
7213 units::volume maxvolume = 0_ml;
7214 auto biggest_container = items.end();
7215 for( auto candidate = items.begin(); candidate != items.end(); ++candidate ) {
7216 if( candidate->is_funnel_container( maxvolume ) ) {
7217 biggest_container = candidate;
7218 }
7219 }
7220 if( biggest_container != items.end() ) {
7221 retroactively_fill_from_funnel( *biggest_container, tr, since, calendar::turn, getabs( p ) );
7222 }
7223}
void retroactively_fill_from_funnel(item &it, const trap &tr, const time_point &start, const time_point &end, const tripoint &pos)
Determine what a funnel has filled out of game, using funnelcontainer.bday as a starting point.
Definition: weather.cpp:184

References getabs(), has_flag_ter_or_furn(), i_at(), retroactively_fill_from_funnel(), TFLAG_INDOORS, tr_at(), and calendar::turn.

Referenced by actualize().

◆ find_clear_path()

std::vector< tripoint > map::find_clear_path ( const tripoint source,
const tripoint destination 
) const

Iteratively tries Bresenham lines with different biases until it finds a clear line or decides there isn't one.

returns the line found, which may be the straight line, but blocked.

Definition at line 6335 of file map.cpp.

6337{
6338 // TODO: Push this junk down into the Bresenham method, it's already doing it.
6339 const point d( destination.xy() - source.xy() );
6340 const point a( std::abs( d.x ) * 2, std::abs( d.y ) * 2 );
6341 const int dominant = std::max( a.x, a.y );
6342 const int minor = std::min( a.x, a.y );
6343 // This seems to be the method for finding the ideal start value for the error value.
6344 const int ideal_start_offset = minor - dominant / 2;
6345 const int start_sign = ( ideal_start_offset > 0 ) - ( ideal_start_offset < 0 );
6346 // Not totally sure of the derivation.
6347 const int max_start_offset = std::abs( ideal_start_offset ) * 2 + 1;
6348 for( int horizontal_offset = -1; horizontal_offset <= max_start_offset; ++horizontal_offset ) {
6349 int candidate_offset = horizontal_offset * start_sign;
6350 if( sees( source, destination, rl_dist( source, destination ), candidate_offset ) ) {
6351 return line_to( source, destination, candidate_offset, 0 );
6352 }
6353 }
6354 // If we couldn't find a clear LoS, just return the ideal one.
6355 return line_to( source, destination, ideal_start_offset, 0 );
6356}
bool sees(const tripoint &F, const tripoint &T, int range) const
Returns whether F sees T with a view range of range.
Definition: map.cpp:6203

References a, line_to(), minor, rl_dist(), sees(), point::x, tripoint::xy(), and point::y.

Referenced by mattack::boomer(), mattack::boomer_glow(), leap_actor::call(), mattack::flame(), projectile_attack(), mattack::ranged_pull(), target_ui::set_cursor_pos(), and ranged::targetable_creatures().

◆ find_furnitures_or_vparts_with_flag_in_radius()

std::list< tripoint > map::find_furnitures_or_vparts_with_flag_in_radius ( const tripoint center,
size_t  radius,
const std::string &  flag,
size_t  radiusz = 0 
)

returns positions of furnitures or vehicle parts with matching flag in the specified radius

Definition at line 8765 of file map.cpp.

8767{
8768 std::list<tripoint> locs;
8769 for( const auto &loc : points_in_radius( center, radius, radiusz ) ) {
8770 // workaround for ramp bridges
8771 int dz = 0;
8772 if( has_flag( TFLAG_RAMP_UP, loc ) ) {
8773 dz = 1;
8774 } else if( has_flag( TFLAG_RAMP_DOWN, loc ) ) {
8775 dz = -1;
8776 }
8777
8778 if( dz == 0 ) {
8779 if( has_flag_furn_or_vpart( flag, loc ) ) {
8780 locs.push_back( loc );
8781 }
8782 } else {
8783 const tripoint newloc( loc + tripoint( 0, 0, dz ) );
8784 if( has_flag_furn_or_vpart( flag, newloc ) ) {
8785 locs.push_back( newloc );
8786 }
8787 }
8788 }
8789
8790 return locs;
8791}
bool has_flag_furn_or_vpart(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2415

References center, has_flag(), has_flag_furn_or_vpart(), points_in_radius(), TFLAG_RAMP_DOWN, and TFLAG_RAMP_UP.

Referenced by activity_handlers::operation_do_turn(), activity_handlers::operation_finish(), and player_on_couch().

◆ find_furnitures_with_flag_in_radius()

std::list< tripoint > map::find_furnitures_with_flag_in_radius ( const tripoint center,
size_t  radius,
const std::string &  flag,
size_t  radiusz = 0 
)

returns positions of furnitures with matching flag in the specified radius

Definition at line 8751 of file map.cpp.

8755{
8756 std::list<tripoint> furn_locs;
8757 for( const auto &furn_loc : points_in_radius( center, radius, radiusz ) ) {
8758 if( has_flag_furn( flag, furn_loc ) ) {
8759 furn_locs.push_back( furn_loc );
8760 }
8761 }
8762 return furn_locs;
8763}

References center, has_flag_furn(), and points_in_radius().

◆ flammable_items_at()

bool map::flammable_items_at ( const tripoint p,
int  threshold = 0 
)

Checks if there are any flammable items on the tile.

Parameters
ptile to check
thresholdFuel threshold (lower means worse fuels are accepted).

Definition at line 2694 of file map.cpp.

2695{
2696 if( !has_items( p ) ||
2698 // Sealed containers don't allow fire, so shouldn't allow setting the fire either
2699 return false;
2700 }
2701
2702 for( const auto &i : i_at( p ) ) {
2703 if( i.flammable( threshold ) ) {
2704 return true;
2705 }
2706 }
2707
2708 return false;
2709}
@ TFLAG_ALLOW_FIELD_EFFECT
Definition: mapdata.h:286

References has_flag(), has_items(), i_at(), TFLAG_ALLOW_FIELD_EFFECT, and TFLAG_SEALED.

Referenced by MapExtras::burned_ground_parser(), is_flammable(), firestarter_actor::moves_cost_by_fuel(), process_fields_in_submap(), and item::process_litcig().

◆ free_volume()

units::volume map::free_volume ( const tripoint p)

Definition at line 4289 of file map.cpp.

4290{
4291 return i_at( p ).free_volume();
4292}
units::volume free_volume() const
Definition: item_stack.cpp:141

References item_stack::free_volume(), and i_at().

Referenced by activity_on_turn_move_loot(), add_item_or_charges(), and advanced_inv_area::free_volume().

◆ function_over()

template<typename Functor >
void map::function_over ( const tripoint start,
const tripoint end,
Functor  fun 
) const
private

Runs a functor over given submaps over submaps in the area, getting next submap only when the current one "runs out" rather than every time.

gp in the functor is Grid (like get_submap_at_grid) coordinate of the submap, Will silently clip the area to map bounds.

Parameters
startStarting point for function
endEnd point for function
funFunction to run

Definition at line 8565 of file map.cpp.

8566{
8567 // start and end are just two points, end can be "before" start
8568 // Also clip the area to map area
8569 const tripoint min( std::max( std::min( start.x, end.x ), 0 ), std::max( std::min( start.y, end.y ),
8570 0 ), std::max( std::min( start.z, end.z ), -OVERMAP_DEPTH ) );
8571 const tripoint max( std::min( std::max( start.x, end.x ), SEEX * my_MAPSIZE - 1 ),
8572 std::min( std::max( start.y, end.y ), SEEY * my_MAPSIZE - 1 ), std::min( std::max( start.z, end.z ),
8573 OVERMAP_HEIGHT ) );
8574
8575 // Submaps that contain the bounding points
8576 const point min_sm( min.x / SEEX, min.y / SEEY );
8577 const point max_sm( max.x / SEEX, max.y / SEEY );
8578 // Z outermost, because submaps are flat
8579 tripoint gp;
8580 int &z = gp.z;
8581 int &smx = gp.x;
8582 int &smy = gp.y;
8583 for( z = min.z; z <= max.z; z++ ) {
8584 for( smx = min_sm.x; smx <= max_sm.x; smx++ ) {
8585 for( smy = min_sm.y; smy <= max_sm.y; smy++ ) {
8586 submap const *cur_submap = get_submap_at_grid( { smx, smy, z } );
8587 // Bounds on the submap coordinates
8588 const point sm_min( smx > min_sm.x ? 0 : min.x % SEEX, smy > min_sm.y ? 0 : min.y % SEEY );
8589 const point sm_max( smx < max_sm.x ? SEEX - 1 : max.x % SEEX,
8590 smy < max_sm.y ? SEEY - 1 : max.y % SEEY );
8591
8592 point lp;
8593 int &sx = lp.x;
8594 int &sy = lp.y;
8595 for( sx = sm_min.x; sx <= sm_max.x; ++sx ) {
8596 for( sy = sm_min.y; sy <= sm_max.y; ++sy ) {
8597 const iteration_state rval = fun( gp, cur_submap, lp );
8598 if( rval != ITER_CONTINUE ) {
8599 switch( rval ) {
8600 case ITER_SKIP_ZLEVEL:
8601 smx = my_MAPSIZE + 1;
8602 smy = my_MAPSIZE + 1;
8603 // Fall through
8604 case ITER_SKIP_SUBMAP:
8605 sx = SEEX;
8606 sy = SEEY;
8607 break;
8608 default:
8609 return;
8610 }
8611 }
8612 }
8613 }
8614 }
8615 }
8616 }
8617}
iteration_state
Enum used by functors in function_over to control execution.
Definition: map.h:1916

References get_submap_at_grid(), ITER_CONTINUE, ITER_SKIP_SUBMAP, ITER_SKIP_ZLEVEL, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, SEEX, SEEY, sx, sy, point::x, tripoint::x, point::y, tripoint::y, and tripoint::z.

Referenced by scent_blockers().

◆ furn() [1/2]

furn_id map::furn ( const tripoint p) const

Definition at line 1406 of file map.cpp.

1407{
1408 if( !inbounds( p ) ) {
1409 return f_null;
1410 }
1411
1412 point l;
1413 submap *const current_submap = get_submap_at( p, l );
1414
1415 return current_submap->get_furn( l );
1416}
furn_id get_furn(point p) const
Definition: submap.h:86

References f_null, submap::get_furn(), get_submap_at(), and inbounds().

Referenced by computer_session::action_blood_anal(), computer_session::action_sample(), actualize(), ter_furn_transform::add_all_messages(), iexamine::arcfurnace_empty(), iexamine::arcfurnace_full(), iexamine::autoclave_full(), bash_furn_success(), bash_rating(), bash_resistance(), bash_strength(), bash_ter_furn(), board_up(), MapExtras::burned_ground_parser(), can_construct(), can_examine_at(), can_move_furniture(), construct::check_deconstruct(), vehicle::autodrive_controller::check_drivable(), deploy_tent_actor::check_intact(), activity_handlers::chop_tree_finish(), close_door(), doors::close_door(), coverage(), create_anomaly(), MapExtras::dead_vegetation_parser(), iexamine::deployed_furniture(), destroy_furn(), displace_items_except_one_liquid(), game::do_turn(), construct::done_deconstruct(), editmap_hilight::draw(), draw_lab(), editmap::draw_main_ui_overlay(), drop_furniture(), Character::env_surgery_bonus(), examine(), game::examine(), game::extended_description(), computer_session::failure_destroy_blood(), farm_action(), feature< furn_id >(), iexamine::fertilize_plant(), talk_function::field_harvest(), activity_handlers::fill_liquid_do_turn(), find_base_construction(), find_potential_computer_point(), iexamine::fireplace(), Character::floor_bedding_warmth(), inventory::form_from_map(), furn(), furn_is_supported(), furnname(), generic_multi_activity_locations(), get_changed_ids_from_update(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::get_fake_tool(), get_furn_transforms_into(), get_hack_type(), get_harvest(), get_harvest_names(), get_keg_capacity(), grab(), game::grabbed_furn_move(), grow_plant(), activity_handlers::hacksaw_finish(), iexamine::harvest_plant(), has_adjacent_furniture_with(), has_flag_furn(), has_furn(), has_pre_terrain(), is_bashable(), is_bashable_furn(), iexamine::kiln_empty(), iexamine::kiln_full(), talk_function::loot_building(), map_stack::max_volume(), mill_activate(), iexamine::mill_finalize(), mill_load_food(), avatar_action::move(), move_cost(), obstacle_coverage(), om_harvest_furn(), iexamine::on_smoke_out(), open_door(), activity_handlers::oxytorch_finish(), tutorial_game::per_turn(), Character::place_corpse(), game::place_player(), mission_start::place_priest_diary(), activity_handlers::plant_seed_finish(), iexamine::portable_structure(), game::print_terrain_info(), item::process_fake_mill(), item::process_fake_smoke(), iexamine::quern_examine(), rad_scorch(), iexamine::reload_furniture(), resolve_regional_terrain_and_furniture(), set_item_map_or_vehicle(), smash(), smoker_activate(), smoker_finalize(), smoker_load_food(), iexamine::smoker_options(), fungal_effects::spread_fungus_one_tile(), ter_furn_transform::transform(), avatar_funcs::try_to_sleep(), editmap::update_view_with_help(), pick_lock_actor::use(), use_charges(), iexamine::use_furn_fake_item(), game::walk_move(), water_from(), and workbench_crafting_speed_multiplier().

◆ furn() [2/2]

furn_id map::furn ( point  p) const
inline

Definition at line 792 of file map.h.

792 {
793 return furn( tripoint( p, abs_sub.z ) );
794 }

References abs_sub, furn(), and tripoint::z.

◆ furn_set() [1/2]

void map::furn_set ( const tripoint p,
const furn_id new_furniture,
cata::poly_serialized< active_tile_data new_active = nullptr 
)

Sets the furniture at given position.

Parameters
pPosition within the map
new_furnitureId of new furniture
new_activeOverride default active tile of new furniture

Definition at line 1418 of file map.cpp.

1420{
1421 if( !inbounds( p ) ) {
1422 return;
1423 }
1424
1425 point l;
1426 submap *const current_submap = get_submap_at( p, l );
1427 const furn_id old_id = current_submap->get_furn( l );
1428 if( old_id == new_furniture ) {
1429 // Nothing changed
1430 return;
1431 }
1432
1433 current_submap->set_furn( l, new_furniture );
1434
1435 // Set the dirty flags
1436 const furn_t &old_t = old_id.obj();
1437 const furn_t &new_t = new_furniture.obj();
1438
1439 // If player has grabbed this furniture and it's no longer grabbable, release the grab.
1440 if( g->u.get_grab_type() == OBJECT_FURNITURE && g->u.grab_point == p && !new_t.is_movable() ) {
1441 add_msg( _( "The %s you were grabbing is destroyed!" ), old_t.name() );
1442 g->u.grab( OBJECT_NONE );
1443 }
1444 // If a creature was crushed under a rubble -> free it
1445 if( old_id == f_rubble && new_furniture == f_null ) {
1446 Creature *c = g->critter_at( p );
1447 if( c ) {
1448 c->remove_effect( effect_crushed );
1449 }
1450 }
1451 if( new_t.has_flag( "EMITTER" ) ) {
1452 field_furn_locs.push_back( p );
1453 }
1454 if( old_t.transparent != new_t.transparent ) {
1457 }
1458
1459 if( old_t.has_flag( TFLAG_INDOORS ) != new_t.has_flag( TFLAG_INDOORS ) ) {
1461 }
1462
1463 if( old_t.has_flag( TFLAG_NO_FLOOR ) != new_t.has_flag( TFLAG_NO_FLOOR ) ) {
1466 }
1467
1468 if( old_t.has_flag( TFLAG_SUN_ROOF_ABOVE ) != new_t.has_flag( TFLAG_SUN_ROOF_ABOVE ) ) {
1469 set_floor_cache_dirty( p.z + 1 );
1470 }
1471
1473
1475
1476 // TODO: Limit to changes that affect move cost, traps and stairs
1478
1479 // Make sure the furniture falls if it needs to
1480 support_dirty( p );
1481 tripoint above( p.xy(), p.z + 1 );
1482 // Make sure that if we supported something and no longer do so, it falls down
1483 support_dirty( above );
1484
1485 if( old_t.active ) {
1486 current_submap->active_furniture.erase( point_sm_ms( l ) );
1487 // TODO: Only for g->m? Observer pattern?
1489 }
1490 if( new_t.active || new_active ) {
1492 if( new_active ) {
1493 atd = new_active;
1494 } else {
1495 atd = new_t.active->clone();
1496 atd->set_last_updated( calendar::turn );
1497 }
1498 current_submap->active_furniture[point_sm_ms( l )] = atd;
1500 }
1501}
Copyable unique_ptr that writes and reads objects of derived types.
void on_changed(const tripoint_abs_ms &p)
Updates grid at given global map square coordinate.
void set_floor_cache_dirty(const int zlev)
Definition: map.cpp:234
void set_memory_seen_cache_dirty(const tripoint &p)
Definition: map.cpp:8899
std::map< point_sm_ms, cata::poly_serialized< active_tile_data > > active_furniture
Definition: submap.h:221
void set_furn(point p, furn_id furn)
Definition: submap.h:90
coords::coord_point< point, coords::origin::submap, coords::ms > point_sm_ms
Definition: coordinates.h:473
coords::coord_point< tripoint, coords::origin::abs, coords::ms > tripoint_abs_ms
Definition: coordinates.h:486
distribution_grid_tracker & get_distribution_grid_tracker()
Returns distribution grid tracker that is a part of the global game *g.
Definition: game.cpp:12024
@ OBJECT_NONE
Definition: enums.h:187
@ OBJECT_FURNITURE
Definition: enums.h:197
bool is_movable() const
Definition: mapdata.cpp:1523
cata::poly_serialized< active_tile_data > active
Definition: mapdata.h:523
std::string name() const
Definition: mapdata.cpp:513

References _, furn_t::active, submap::active_furniture, add_msg(), c, effect_crushed, f_null, f_rubble, field_furn_locs, g, get_distribution_grid_tracker(), submap::get_furn(), get_submap_at(), getabs(), map_data_common_t::has_flag(), inbounds(), invalidate_max_populated_zlev(), furn_t::is_movable(), map_data_common_t::name(), int_id< T >::obj(), OBJECT_FURNITURE, OBJECT_NONE, distribution_grid_tracker::on_changed(), set_floor_cache_dirty(), submap::set_furn(), set_memory_seen_cache_dirty(), set_outside_cache_dirty(), set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_transparency_cache_dirty(), support_dirty(), TFLAG_INDOORS, TFLAG_NO_FLOOR, TFLAG_SUN_ROOF_ABOVE, map_data_common_t::transparent, calendar::turn, tripoint::xy(), and tripoint::z.

Referenced by iexamine::aggie_plant(), grid_furn_transform_queue::apply(), jmapgen_sign::apply(), jmapgen_vending_machine::apply(), jmapgen_toilet::apply(), jmapgen_gaspump::apply(), jmapgen_furniture::apply(), jmapgen_terrain::apply(), jmapgen_computer::apply(), jmapgen_sealed_item::apply(), jmapgen_setmap::apply(), apply< furn_t >(), iexamine::arcfurnace_empty(), iexamine::arcfurnace_full(), iexamine::autoclave_full(), bash_furn_success(), board_up(), MapExtras::burned_ground_parser(), activity_handlers::clear_rubble_finish(), close_door(), collapse_at(), collapse_invalid_suspension(), complete_construction(), activity_handlers::cracking_finish(), create_anomaly(), MapExtras::dead_vegetation_parser(), iexamine::deployed_furniture(), displace_items_except_one_liquid(), construct::done_deconstruct(), draw_circle_furn(), draw_lab(), draw_line_furn(), draw_rough_circle_furn(), draw_square_furn(), drop_furniture(), iexamine::egg_sack_generic(), farm_action(), iexamine::fertilize_plant(), talk_function::field_harvest(), activity_handlers::fill_liquid_do_turn(), dig_activity_actor::finish(), hacking_activity_actor::finish(), iexamine::fireplace(), iexamine::flower_cactus(), iexamine::flower_dahlia(), iexamine::flower_marloss(), iexamine::flower_poppy(), mapgen_function_json_base::formatted_set_incredibly_simple(), mapf::formatted_set_simple(), iexamine::fungus(), furn_set(), iexamine::fvat_empty(), iexamine::fvat_full(), game::grabbed_furn_move(), grow_plant(), activity_handlers::hacksaw_finish(), iexamine::harvest_furn(), iexamine::harvest_furn_nectar(), iexamine::harvest_plant(), iexamine::kiln_empty(), iexamine::kiln_full(), talk_function::loot_building(), make_rubble(), mapgen_forest(), mapgen_forest_trail_curved(), mapgen_forest_trail_four_way(), mapgen_forest_trail_straight(), mapgen_forest_trail_tee(), mapgen_lake_shore(), mapgen_tutorial(), iexamine::migo_nerve_cluster(), mill_activate(), iexamine::mill_finalize(), MapExtras::mx_burned_ground(), MapExtras::mx_clay_deposit(), MapExtras::mx_grave(), MapExtras::mx_house_spider(), MapExtras::mx_minefield(), MapExtras::mx_pond(), MapExtras::mx_roadworks(), MapExtras::mx_spider(), MapExtras::mx_supplydrop(), om_harvest_furn(), open_door(), iexamine::open_safe(), activity_handlers::oxytorch_finish(), place_toilet(), place_vending(), activity_handlers::plant_seed_finish(), iexamine::portable_structure(), process_fields_in_submap(), iexamine::quern_examine(), rad_scorch(), mission_start::ranch_nurse_9(), mission_start::ranch_scavenger_3(), resolve_regional_terrain_and_furniture(), iexamine::safe(), science_room(), set(), smoker_activate(), smoker_finalize(), iexamine::smoker_options(), fungal_effects::spread_fungus_one_tile(), ter_or_furn_set(), ter_furn_transform::transform(), deploy_furn_actor::use(), deploy_tent_actor::use(), and game::vertical_move().

◆ furn_set() [2/2]

void map::furn_set ( point  p,
const furn_id new_furniture 
)
inline

Definition at line 804 of file map.h.

804 {
805 furn_set( tripoint( p, abs_sub.z ), new_furniture );
806 }

References abs_sub, furn_set(), and tripoint::z.

◆ furnname() [1/2]

std::string map::furnname ( const tripoint p)

Definition at line 1527 of file map.cpp.

1528{
1529 const furn_t &f = furn( p ).obj();
1530 if( f.has_flag( "PLANT" ) ) {
1531 // Can't use item_stack::only_item() since there might be fertilizer
1532 map_stack items = i_at( p );
1533 const map_stack::iterator seed = std::find_if( items.begin(), items.end(), []( const item & it ) {
1534 return it.is_seed();
1535 } );
1536 if( seed == items.end() ) {
1537 debugmsg( "Missing seed for plant at (%d, %d, %d)", p.x, p.y, p.z );
1538 return "null";
1539 }
1540 const std::string &plant = seed->get_plant_name();
1541 return string_format( "%s (%s)", f.name(), plant );
1542 } else {
1543 return f.name();
1544 }
1545}
iterator begin()
Definition: item_stack.cpp:28
iterator end()
Definition: item_stack.cpp:33
Definition: map.h:105
int seed(player *, item *, bool, const tripoint &)
Definition: iuse.cpp:6006

References item_stack::begin(), debugmsg, item_stack::end(), furn(), map_data_common_t::has_flag(), i_at(), map_data_common_t::name(), int_id< T >::obj(), plant, iuse::seed(), string_format(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by apply_lock_picking_tool(), apply_prying_tool(), vehicle::check_heli_ascend(), activity_handlers::clear_rubble_finish(), iexamine::egg_sack_generic(), iexamine::fireplace(), iexamine::flower_cactus(), iexamine::flower_dahlia(), iexamine::flower_marloss(), iexamine::flower_poppy(), iexamine::fungus(), furnname(), grab(), harvest_common(), iexamine::locked_object(), iexamine::locked_object_pickable(), name(), game::place_player(), game::print_terrain_info(), iexamine::reload_furniture(), iexamine::rubble(), smash(), and deploy_tent_actor::use().

◆ furnname() [2/2]

std::string map::furnname ( point  p)
inline

Definition at line 808 of file map.h.

808 {
809 return furnname( tripoint( p, abs_sub.z ) );
810 }
std::string furnname(const tripoint &p)
Definition: map.cpp:1527

References abs_sub, furnname(), and tripoint::z.

◆ gas_can_spread_to()

bool map::gas_can_spread_to ( field_entry cur,
const tripoint src,
const tripoint dst 
)
private

Definition at line 211 of file map_field.cpp.

212{
213 maptile dst_tile = maptile_at( dst );
214 const field_entry *tmpfld = dst_tile.get_field().find_field( cur.get_field_type() );
215 // Candidates are existing weaker fields or navigable/flagged tiles with no field.
216 if( tmpfld == nullptr || tmpfld->get_field_intensity() < cur.get_field_intensity() ) {
217 const ter_t &ter = dst_tile.get_ter_t();
218 const furn_t &frn = dst_tile.get_furn_t();
219 return !obstructed_by_vehicle_rotation( src, dst ) &&
220 ( ter_furn_movecost( ter, frn ) > 0 || ter_furn_has_flag( ter, frn, TFLAG_PERMEABLE ) );
221 }
222 return false;
223}
bool ter_furn_has_flag(const ter_t &ter, const furn_t &furn, const ter_bitflags flag)
Definition: map_field.cpp:161
static int ter_furn_movecost(const ter_t &ter, const furn_t &furn)
Definition: map_field.cpp:166
@ TFLAG_PERMEABLE
Definition: mapdata.h:304
const ter_t & get_ter_t() const
Definition: submap.h:271
const field & get_field() const
Definition: submap.h:275
const furn_t & get_furn_t() const
Definition: submap.h:268

References field::find_field(), maptile::get_field(), field_entry::get_field_intensity(), field_entry::get_field_type(), maptile::get_furn_t(), maptile::get_ter_t(), maptile_at(), obstructed_by_vehicle_rotation(), ter(), ter_furn_has_flag(), ter_furn_movecost(), and TFLAG_PERMEABLE.

Referenced by spread_gas().

◆ gas_spread_to()

void map::gas_spread_to ( field_entry cur,
maptile dst,
const tripoint p 
)
private

Definition at line 225 of file map_field.cpp.

226{
227 const field_type_id current_type = cur.get_field_type();
228 const time_duration current_age = cur.get_field_age();
229 const int current_intensity = cur.get_field_intensity();
230 field_entry *f = dst.find_field( current_type );
231 // Nearby gas grows thicker, and ages are shared.
232 const time_duration age_fraction = current_age / current_intensity;
233 if( f != nullptr ) {
235 cur.set_field_intensity( current_intensity - 1 );
236 f->set_field_age( f->get_field_age() + age_fraction );
237 cur.set_field_age( current_age - age_fraction );
238 // Or, just create a new field.
239 } else if( add_field( p, current_type, 1, 0_turns ) ) {
240 f = dst.find_field( current_type );
241 if( f != nullptr ) {
242 f->set_field_age( age_fraction );
243 } else {
244 debugmsg( "While spreading the gas, field was added but doesn't exist." );
245 }
246 cur.set_field_intensity( current_intensity - 1 );
247 cur.set_field_age( current_age - age_fraction );
248 }
249}
int set_field_intensity(int new_intensity)
Definition: field.cpp:126
field_entry * find_field(const field_type_id &field_to_find)
Definition: submap.h:279

References add_field(), debugmsg, maptile::find_field(), field_entry::get_field_age(), field_entry::get_field_intensity(), field_entry::get_field_type(), field_entry::set_field_age(), and field_entry::set_field_intensity().

Referenced by spread_gas().

◆ generate()

void map::generate ( const tripoint p,
const time_point when 
)

Definition at line 107 of file mapgen.cpp.

108{
109 dbg( DL::Info ) << "map::generate( g[" << g.get() << "], p[" << p <<
110 "], when[" << to_string( when ) << "] )";
111
112 set_abs_sub( p );
113
114 // First we have to create new submaps and initialize them to 0 all over
115 // We create all the submaps, even if we're not a tinymap, so that map
116 // generation which overflows won't cause a crash. At the bottom of this
117 // function, we save the upper-left 4 submaps, and delete the rest.
118 // Mapgen is not z-level aware yet. Only actually initialize current z-level
119 // because other submaps won't be touched.
120 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
121 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
122 const size_t grid_pos = get_nonant( { gridx, gridy, p.z } );
123 if( getsubmap( grid_pos ) ) {
124 debugmsg( "Submap already exists at (%d, %d, %d)", gridx, gridy, p.z );
125 continue;
126 }
127 setsubmap( grid_pos, new submap() );
128 // TODO: memory leak if the code below throws before the submaps get stored/deleted!
129 }
130 }
131 // x, and y are submap coordinates, convert to overmap terrain coordinates
132 // TODO: fix point types
133 tripoint_abs_omt abs_omt( sm_to_omt_copy( p ) );
134 oter_id terrain_type = overmap_buffer.ter( abs_omt );
135
136 // This attempts to scale density of zombies inversely with distance from the nearest city.
137 // In other words, make city centers dense and perimeters sparse.
138 float density = 0.0;
139 for( int i = -MON_RADIUS; i <= MON_RADIUS; i++ ) {
140 for( int j = -MON_RADIUS; j <= MON_RADIUS; j++ ) {
141 density += overmap_buffer.ter( abs_omt + point( i, j ) )->get_mondensity();
142 }
143 }
144 density = density / 100;
145
146 mapgendata dat( abs_omt, *this, density, when, nullptr );
147 draw_map( dat );
148
149 // At some point, we should add region information so we can grab the appropriate extras
150 map_extras ex = region_settings_map["default"].region_extras[terrain_type->get_extras()];
151 if( ex.chance > 0 && one_in( ex.chance ) ) {
152 std::string *extra = ex.values.pick();
153 if( extra == nullptr ) {
154 debugmsg( "failed to pick extra for type %s", terrain_type->get_extras() );
155 } else {
156 MapExtras::apply_function( *( ex.values.pick() ), *this, abs_sub );
157 }
158 }
159
160 const auto &spawns = terrain_type->get_static_spawns();
161
162 float spawn_density = 1.0f;
163 if( MonsterGroupManager::is_animal( spawns.group ) ) {
164 spawn_density = get_option< float >( "SPAWN_ANIMAL_DENSITY" );
165 } else {
166 spawn_density = get_option< float >( "SPAWN_DENSITY" );
167 }
168
169 // Apply a multiplier to the number of monsters for really high densities.
170 float odds_after_density = spawns.chance * spawn_density;
171 const float max_odds = 100 - ( 100 - spawns.chance ) / 2.0;
172 float density_multiplier = 1.0f;
173 if( odds_after_density > max_odds ) {
174 density_multiplier = 1.0f * odds_after_density / max_odds;
175 odds_after_density = max_odds;
176 }
177 const int spawn_count = roll_remainder( density_multiplier );
178
179 if( spawns.group && x_in_y( odds_after_density, 100 ) ) {
180 int pop = spawn_count * rng( spawns.population.min, spawns.population.max );
181 for( ; pop > 0; pop-- ) {
182 MonsterGroupResult spawn_details = MonsterGroupManager::GetResultFromGroup( spawns.group, &pop );
183 if( !spawn_details.name ) {
184 continue;
185 }
186 if( const cata::optional<tripoint> pt =
187 random_point( *this, [this]( const tripoint & n ) {
188 return passable( n );
189 } ) ) {
190 add_spawn( spawn_details.name, spawn_details.pack_size, *pt );
191 }
192 }
193 }
194
195 // Okay, we know who are neighbors are. Let's draw!
196 // And finally save used submaps and delete the rest.
197 for( int i = 0; i < my_MAPSIZE; i++ ) {
198 for( int j = 0; j < my_MAPSIZE; j++ ) {
199 dbg( DL::Info ) << "map::generate: submap (" << i << "," << j << ")";
200
201 const tripoint pos( i, j, p.z );
202 if( i <= 1 && j <= 1 ) {
203 saven( pos );
204 } else {
205 const size_t grid_pos = get_nonant( pos );
206 delete getsubmap( grid_pos );
207 setsubmap( grid_pos, nullptr );
208 }
209 }
210 }
211}
std::string to_string(const time_duration &d)
Returns a string showing a duration.
Definition: calendar.cpp:327
static bool is_animal(const mongroup_id &group)
Definition: mongroup.cpp:401
static MonsterGroupResult GetResultFromGroup(const mongroup_id &group, int *quantity=nullptr)
Definition: mongroup.cpp:98
void saven(const tripoint &grid)
Definition: map.cpp:7011
void set_abs_sub(const tripoint &p)
Sets abs_sub, see there.
Definition: map.cpp:8345
void draw_map(mapgendata &dat)
Definition: mapgen.cpp:2915
submap * getsubmap(size_t grididx) const
Get the submap pointer with given index in grid, the index must be valid!
Definition: map.cpp:8355
void add_spawn(const mtype_id &type, int count, const tripoint &p, bool friendly=false, int faction_id=-1, int mission_id=-1, const std::string &name="NONE") const
Definition: mapgen.cpp:5615
bool passable(const tripoint &p) const
Definition: map.cpp:1858
Contains various information regarding the individual mapgen instance (generating a specific part of ...
Definition: mapgendata.h:36
const oter_id & ter(const tripoint_abs_omt &p)
Returns the overmap terrain at the given OMT coordinates.
point sm_to_omt_copy(point p)
static constexpr int MON_RADIUS
Definition: mapgen.cpp:101
void apply_function(const string_id< map_extra > &id, map &m, const tripoint &abs_sub)
t_regional_settings_map region_settings_map
Definition: overmap.cpp:186
mtype_id name
Definition: mongroup.h:53
unsigned int chance
weighted_int_list< std::string > values
const std::string & get_extras() const
Definition: omdata.h:237
const overmap_static_spawns & get_static_spawns() const
Definition: omdata.h:245
int get_mondensity() const
Definition: omdata.h:241

References abs_sub, add_spawn(), MapExtras::apply_function(), map_extras::chance, dbg, debugmsg, draw_map(), g, oter_t::get_extras(), oter_t::get_mondensity(), get_nonant(), oter_t::get_static_spawns(), MonsterGroupManager::GetResultFromGroup(), getsubmap(), Info, MonsterGroupManager::is_animal(), MON_RADIUS, my_MAPSIZE, MonsterGroupResult::name, one_in(), overmap_buffer, MonsterGroupResult::pack_size, passable(), random_point(), region_settings_map, rng(), roll_remainder(), saven(), set_abs_sub(), setsubmap(), sm_to_omt_copy(), overmapbuffer::ter(), to_string(), map_extras::values, x_in_y(), and tripoint::z.

Referenced by farm_action(), defense_game::init_map(), loadn(), and editmap::mapgen_preview().

◆ generate_lightmap()

void map::generate_lightmap ( int  zlev)
protected

Definition at line 400 of file lightmap.cpp.

401{
402 auto &map_cache = get_cache( zlev );
403 auto &lm = map_cache.lm;
404 auto &sm = map_cache.sm;
405 auto &outside_cache = map_cache.outside_cache;
406 auto &prev_floor_cache = get_cache( clamp( zlev + 1, -OVERMAP_DEPTH, OVERMAP_DEPTH ) ).floor_cache;
407 bool top_floor = zlev == OVERMAP_DEPTH;
408 std::memset( lm, 0, sizeof( lm ) );
409 std::memset( sm, 0, sizeof( sm ) );
410
411 /* Bulk light sources wastefully cast rays into neighbors; a burning hospital can produce
412 significant slowdown, so for stuff like fire and lava:
413 * Step 1: Store the position and luminance in buffer via add_light_source, for efficient
414 checking of neighbors.
415 * Step 2: After everything else, iterate buffer and apply_light_source only in non-redundant
416 directions
417 * Step 3: ????
418 * Step 4: Profit!
419 */
420 auto &light_source_buffer = map_cache.light_source_buffer;
421 std::memset( light_source_buffer, 0, sizeof( light_source_buffer ) );
422
423 constexpr std::array<int, 4> dir_x = { { 0, -1, 1, 0 } }; // [0]
424 constexpr std::array<int, 4> dir_y = { { -1, 0, 0, 1 } }; // [1][X][2]
425 constexpr std::array<int, 4> dir_d = { { 90, 0, 180, 270 } }; // [3]
426 constexpr std::array<std::array<quadrant, 2>, 4> dir_quadrants = { {
431 }
432 };
433
434 const float natural_light = g->natural_light_level( zlev );
435
436 build_sunlight_cache( zlev );
437
439 for( npc &guy : g->all_npcs() ) {
441 }
442
443 std::vector<std::pair<tripoint, float>> lm_override;
444 // Traverse the submaps in order
445 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
446 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
447 const auto cur_submap = get_submap_at_grid( { smx, smy, zlev } );
448
449 for( int sx = 0; sx < SEEX; ++sx ) {
450 for( int sy = 0; sy < SEEY; ++sy ) {
451 const int x = sx + smx * SEEX;
452 const int y = sy + smy * SEEY;
453 const tripoint p( x, y, zlev );
454 // Project light into any openings into buildings.
455 if( !outside_cache[p.x][p.y] || ( !top_floor && prev_floor_cache[p.x][p.y] ) ) {
456 // Apply light sources for external/internal divide
457 for( int i = 0; i < 4; ++i ) {
458 point neighbour = p.xy() + point( dir_x[i], dir_y[i] );
459 if( lightmap_boundaries.contains( neighbour )
460 && outside_cache[neighbour.x][neighbour.y] &&
461 ( top_floor || !prev_floor_cache[neighbour.x][neighbour.y] )
462 ) {
463 const float source_light =
464 std::min( natural_light, lm[neighbour.x][neighbour.y].max() );
466 update_light_quadrants( lm[p.x][p.y], source_light, quadrant::default_ );
467 apply_directional_light( p, dir_d[i], source_light );
468 } else {
469 update_light_quadrants( lm[p.x][p.y], source_light, dir_quadrants[i][0] );
470 update_light_quadrants( lm[p.x][p.y], source_light, dir_quadrants[i][1] );
471 }
472 }
473 }
474 }
475
476 if( cur_submap->get_lum( { sx, sy } ) && has_items( p ) ) {
477 auto items = i_at( p );
478 add_light_from_items( p, items.begin(), items.end() );
479 }
480
481 const ter_id terrain = cur_submap->get_ter( { sx, sy } );
482 if( terrain->light_emitted > 0 ) {
483 add_light_source( p, terrain->light_emitted );
484 }
485 const furn_id furniture = cur_submap->get_furn( {sx, sy } );
486 if( furniture->light_emitted > 0 ) {
487 add_light_source( p, furniture->light_emitted );
488 }
489
490 for( auto &fld : cur_submap->get_field( { sx, sy } ) ) {
491 const field_entry *cur = &fld.second;
492 const int light_emitted = cur->light_emitted();
493 if( light_emitted > 0 ) {
494 add_light_source( p, light_emitted );
495 }
496 const float light_override = cur->local_light_override();
497 if( light_override >= 0.0 ) {
498 lm_override.push_back( std::pair<tripoint, float>( p, light_override ) );
499 }
500 }
501 }
502 }
503 }
504 }
505
506 for( monster &critter : g->all_monsters() ) {
507 if( critter.is_hallucination() ) {
508 continue;
509 }
510 const tripoint &mp = critter.pos();
511 if( inbounds( mp ) ) {
512 if( critter.has_effect( effect_onfire ) ) {
513 apply_light_source( mp, 8 );
514 }
515 // TODO: [lightmap] Attach natural light brightness to creatures
516 // TODO: [lightmap] Allow creatures to have light attacks (i.e.: eyebot)
517 // TODO: [lightmap] Allow creatures to have facing and arc lights
518 if( critter.type->luminance > 0 ) {
519 apply_light_source( mp, critter.type->luminance );
520 }
521 }
522 }
523
524 // Apply any vehicle light sources
525 VehicleList vehs = get_vehicles();
526 for( auto &vv : vehs ) {
527 vehicle *v = vv.v;
528
529 auto lights = v->lights( true );
530
531 float veh_luminance = 0.0;
532 float iteration = 1.0;
533
534 for( const auto pt : lights ) {
535 const auto &vp = pt->info();
536 if( vp.has_flag( VPFLAG_CONE_LIGHT ) ||
537 vp.has_flag( VPFLAG_WIDE_CONE_LIGHT ) ) {
538 veh_luminance += vp.bonus / iteration;
539 iteration = iteration * 1.1;
540 }
541 }
542
543 for( const auto pt : lights ) {
544 const auto &vp = pt->info();
545 tripoint src = v->global_part_pos3( *pt );
546
547 if( !inbounds( src ) ) {
548 continue;
549 }
550
551 if( vp.has_flag( VPFLAG_CONE_LIGHT ) ) {
552 if( veh_luminance > lit_level::LIT ) {
553 add_light_source( src, M_SQRT2 ); // Add a little surrounding light
554 apply_light_arc( src, v->face.dir() + pt->direction, veh_luminance,
555 45_degrees );
556 }
557
558 } else if( vp.has_flag( VPFLAG_WIDE_CONE_LIGHT ) ) {
559 if( veh_luminance > lit_level::LIT ) {
560 add_light_source( src, M_SQRT2 ); // Add a little surrounding light
561 apply_light_arc( src, v->face.dir() + pt->direction, veh_luminance,
562 90_degrees );
563 }
564
565 } else if( vp.has_flag( VPFLAG_HALF_CIRCLE_LIGHT ) ) {
566 add_light_source( src, M_SQRT2 ); // Add a little surrounding light
567 apply_light_arc( src, v->face.dir() + pt->direction, vp.bonus, 180_degrees );
568
569 } else if( vp.has_flag( VPFLAG_CIRCLE_LIGHT ) ) {
570 const bool odd_turn = calendar::once_every( 2_turns );
571 if( ( odd_turn && vp.has_flag( VPFLAG_ODDTURN ) ) ||
572 ( !odd_turn && vp.has_flag( VPFLAG_EVENTURN ) ) ||
573 ( !( vp.has_flag( VPFLAG_EVENTURN ) || vp.has_flag( VPFLAG_ODDTURN ) ) ) ) {
574
575 add_light_source( src, vp.bonus );
576 }
577
578 } else {
579 add_light_source( src, vp.bonus );
580 }
581 }
582
583 for( const vpart_reference &vp : v->get_all_parts() ) {
584 const size_t p = vp.part_index();
585 const tripoint pp = vp.pos();
586 if( !inbounds( pp ) ) {
587 continue;
588 }
589 if( vp.has_feature( VPFLAG_CARGO ) && !vp.has_feature( "COVERED" ) ) {
590 add_light_from_items( pp, v->get_items( static_cast<int>( p ) ).begin(),
591 v->get_items( static_cast<int>( p ) ).end() );
592 }
593 }
594 }
595
596 /* Now that we have position and intensity of all bulk light sources, apply_ them
597 This may seem like extra work, but take a 12x12 raging inferno:
598 unbuffered: (12^2)*(160*4) = apply_light_ray x 92160
599 buffered: (12*4)*(160) = apply_light_ray x 7680
600 */
601 const tripoint cache_start( 0, 0, zlev );
602 const tripoint cache_end( LIGHTMAP_CACHE_X, LIGHTMAP_CACHE_Y, zlev );
603 for( const tripoint &p : points_in_rectangle( cache_start, cache_end ) ) {
604 if( light_source_buffer[p.x][p.y] > 0.0 ) {
605 apply_light_source( p, light_source_buffer[p.x][p.y] );
606 }
607 }
608 for( const std::pair<tripoint, float> &elem : lm_override ) {
609 lm[elem.first.x][elem.first.y].fill( elem.second );
610 }
611}
float light_emitted() const
Definition: field.cpp:69
float local_light_override() const
Definition: field.cpp:74
float light_transparency(const tripoint &p) const
Definition: lightmap.cpp:660
void apply_directional_light(const tripoint &p, int direction, float luminance)
Definition: lightmap.cpp:1624
void build_sunlight_cache(int pzlev)
Definition: lightmap.cpp:249
void add_light_from_items(const tripoint &p, item_stack::iterator begin, item_stack::iterator end)
Definition: lightmap.cpp:64
void apply_character_light(Character &p)
Definition: lightmap.cpp:227
Definition: npc.h:744
units::angle dir() const
Definition: tileray.cpp:74
std::vector< vehicle_part * > lights(bool active=false)
Get all vehicle lights (excluding any that are destroyed)
Definition: vehicle.cpp:4644
vehicle_stack get_items(int part) const
Definition: vehicle.cpp:5470
bool once_every(const time_duration &event_frequency)
Predicate to handle rate-limiting.
Definition: calendar.cpp:490
@ VPFLAG_CONE_LIGHT
Definition: veh_type.h:35
@ VPFLAG_CIRCLE_LIGHT
Definition: veh_type.h:38
@ VPFLAG_CARGO
Definition: veh_type.h:62
@ VPFLAG_EVENTURN
Definition: veh_type.h:33
@ VPFLAG_WIDE_CONE_LIGHT
Definition: veh_type.h:36
@ VPFLAG_ODDTURN
Definition: veh_type.h:34
@ VPFLAG_HALF_CIRCLE_LIGHT
Definition: veh_type.h:37

References add_light_from_items(), add_light_source(), apply_character_light(), apply_directional_light(), apply_light_arc(), apply_light_source(), item_stack::begin(), build_sunlight_cache(), clamp(), default_, tileray::dir(), effect_onfire, item_stack::end(), vehicle::face, level_cache::floor_cache, furniture, g, vehicle::get_all_parts(), get_cache(), vehicle::get_items(), get_player_character(), get_submap_at_grid(), get_vehicles(), vehicle::global_part_pos3(), has_items(), i_at(), inbounds(), field_entry::light_emitted(), light_transparency(), LIGHT_TRANSPARENCY_SOLID, lightmap_boundaries, LIGHTMAP_CACHE_X, LIGHTMAP_CACHE_Y, vehicle::lights(), LIT, field_entry::local_light_override(), M_SQRT2, my_MAPSIZE, NE, NW, calendar::once_every(), OVERMAP_DEPTH, points_in_rectangle(), SE, SEEX, SEEY, coords::sm, SW, sx, sy, terrain, update_light_quadrants(), VPFLAG_CARGO, VPFLAG_CIRCLE_LIGHT, VPFLAG_CONE_LIGHT, VPFLAG_EVENTURN, VPFLAG_HALF_CIRCLE_LIGHT, VPFLAG_ODDTURN, VPFLAG_WIDE_CONE_LIGHT, point::x, tripoint::x, tripoint::xy(), point::y, and tripoint::y.

Referenced by build_map_cache().

◆ get_abs_sub()

◆ get_active_items_in_radius() [1/2]

std::list< item_location > map::get_active_items_in_radius ( const tripoint center,
int  radius 
) const

Definition at line 8705 of file map.cpp.

8707{
8709}
std::list< item_location > get_active_items_in_radius(const tripoint &center, int radius) const
Definition: map.cpp:8705

References center, get_active_items_in_radius(), and none.

Referenced by npc::find_corpse_to_pulp(), npc::find_dangerous_explosives(), and get_active_items_in_radius().

◆ get_active_items_in_radius() [2/2]

std::list< item_location > map::get_active_items_in_radius ( const tripoint center,
int  radius,
special_item_type  type 
) const

Definition at line 8711 of file map.cpp.

8713{
8714 std::list<item_location> result;
8715
8716 const point minp( center.xy() + point( -radius, -radius ) );
8717 const point maxp( center.xy() + point( radius, radius ) );
8718
8719 const point ming( std::max( minp.x / SEEX, 0 ),
8720 std::max( minp.y / SEEY, 0 ) );
8721 const point maxg( std::min( maxp.x / SEEX, my_MAPSIZE - 1 ),
8722 std::min( maxp.y / SEEY, my_MAPSIZE - 1 ) );
8723
8724 for( const tripoint &abs_submap_loc : submaps_with_active_items ) {
8725 const tripoint submap_loc{ -abs_sub.xy() + abs_submap_loc };
8726 if( submap_loc.x < ming.x || submap_loc.y < ming.y ||
8727 submap_loc.x > maxg.x || submap_loc.y > maxg.y ) {
8728 continue;
8729 }
8730 const point sm_offset( submap_loc.x * SEEX, submap_loc.y * SEEY );
8731
8732 submap *sm = get_submap_at_grid( submap_loc );
8733 std::vector<item_reference> items = type == special_item_type::none ? sm->active_items.get() :
8734 sm->active_items.get_special( type );
8735 for( const auto &elem : items ) {
8736 const tripoint pos( sm_offset + elem.location, submap_loc.z );
8737
8738 if( rl_dist( pos, center ) > radius ) {
8739 continue;
8740 }
8741
8742 if( elem.item_ref ) {
8743 result.emplace_back( map_cursor( pos ), elem.item_ref.get() );
8744 }
8745 }
8746 }
8747
8748 return result;
8749}

References abs_sub, center, get_submap_at_grid(), my_MAPSIZE, none, rl_dist(), SEEX, SEEY, coords::sm, submaps_with_active_items, type, point::x, tripoint::xy(), and point::y.

◆ get_cache()

◆ get_cache_ref()

◆ get_creatures_in_radius()

std::list< Creature * > map::get_creatures_in_radius ( const tripoint center,
size_t  radius,
size_t  radiusz = 0 
)

returns creatures in specified radius

Definition at line 8793 of file map.cpp.

8795{
8796 std::list<Creature *> creatures;
8797 for( const auto &loc : points_in_radius( center, radius, radiusz ) ) {
8798 Creature *tmp_critter = g->critter_at( loc );
8799 if( tmp_critter != nullptr ) {
8800 creatures.push_back( tmp_critter );
8801 }
8802
8803 }
8804 return creatures;
8805}

References center, g, and points_in_radius().

◆ get_dir_circle()

std::vector< tripoint > map::get_dir_circle ( const tripoint f,
const tripoint t 
) const

Calculate next search points surrounding the current position.

Points closer to the target come first. This method leads to straighter lines and prevents weird looking movements away from the target.

Definition at line 6634 of file map.cpp.

6635{
6636 std::vector<tripoint> circle;
6637 circle.resize( 8 );
6638
6639 // The line below can be crazy expensive - we only take the FIRST point of it
6640 const std::vector<tripoint> line = line_to( f, t, 0, 0 );
6641 const std::vector<tripoint> spiral = closest_points_first( f, 1 );
6642 const std::vector<int> pos_index {1, 2, 4, 6, 8, 7, 5, 3};
6643
6644 // All possible constellations (closest_points_first goes clockwise)
6645 // 753 531 312 124 246 468 687 875
6646 // 8 1 7 2 5 4 3 6 1 8 2 7 4 5 6 3
6647 // 642 864 786 578 357 135 213 421
6648
6649 size_t pos_offset = 0;
6650 for( size_t i = 1; i < spiral.size(); i++ ) {
6651 if( spiral[i] == line[0] ) {
6652 pos_offset = i - 1;
6653 break;
6654 }
6655 }
6656
6657 for( size_t i = 1; i < spiral.size(); i++ ) {
6658 if( pos_offset >= pos_index.size() ) {
6659 pos_offset = 0;
6660 }
6661
6662 circle[pos_index[pos_offset++] - 1] = spiral[i];
6663 }
6664
6665 return circle;
6666}
void circle(map *m, const ter_id &type, double x, double y, double rad)
Definition: mapgen.cpp:6532

References circle(), closest_points_first(), line(), and line_to().

Referenced by npc::move_to().

◆ get_field() [1/2]

field & map::get_field ( const tripoint p)
private

Definition at line 8541 of file map.cpp.

8542{
8543 return field_at( p );
8544}

References field_at().

◆ get_field() [2/2]

field_entry * map::get_field ( const tripoint p,
const field_type_id type 
)

◆ get_field_age()

time_duration map::get_field_age ( const tripoint p,
const field_type_id type 
) const

Get the age of a field entry (field_entry::age), if there is no field of that type, returns -1_turns.

Definition at line 5434 of file map.cpp.

5435{
5436 auto field_ptr = field_at( p ).find_field( type );
5437 return field_ptr == nullptr ? -1_turns : field_ptr->get_field_age();
5438}

References field_at(), field::find_field(), field_entry::get_field_age(), and type.

Referenced by game::grabbed_furn_move(), try_fuel_fire(), and game::walk_move().

◆ get_field_intensity()

int map::get_field_intensity ( const tripoint p,
const field_type_id type 
) const

Get the intensity of a field entry (field_entry::intensity), if there is no field of that type, returns 0.

Definition at line 5440 of file map.cpp.

5441{
5442 auto field_ptr = field_at( p ).find_field( type );
5443 return ( field_ptr == nullptr ? 0 : field_ptr->get_field_intensity() );
5444}

References field_at(), field::find_field(), and type.

Referenced by character_funcs::base_comfort_value(), game::grabbed_furn_move(), is_flammable(), propagate_field(), fungal_effects::spread_fungus_one_tile(), avatar_funcs::try_to_sleep(), and game::walk_move().

◆ get_furn_field_locations()

const std::vector< tripoint > & map::get_furn_field_locations ( ) const

Definition at line 7821 of file map.cpp.

7822{
7823 return field_furn_locs;
7824}

References field_furn_locs.

Referenced by game::do_turn().

◆ get_furn_transforms_into()

furn_id map::get_furn_transforms_into ( const tripoint p) const

Definition at line 1670 of file map.cpp.

1671{
1672 return furn( p ).obj().transforms_into.id();
1673}
furn_str_id transforms_into
Definition: mapdata.h:503

References furn(), string_id< T >::id(), int_id< T >::obj(), and furn_t::transforms_into.

◆ get_harvest()

const harvest_id & map::get_harvest ( const tripoint p) const

Returns the full harvest list, for spawning.

Definition at line 1622 of file map.cpp.

1623{
1624 const auto furn_here = furn( pos );
1625 if( furn_here->examine != iexamine::none ) {
1626 // Note: if furniture can be examined, the terrain can NOT (until furniture is removed)
1627 if( furn_here->has_flag( TFLAG_HARVESTED ) ) {
1628 return harvest_id::NULL_ID();
1629 }
1630
1631 return furn_here->get_harvest();
1632 }
1633
1634 const auto ter_here = ter( pos );
1635 if( ter_here->has_flag( TFLAG_HARVESTED ) ) {
1636 return harvest_id::NULL_ID();
1637 }
1638
1639 return ter_here->get_harvest();
1640}
static const string_id< harvest_list > & NULL_ID()
Returns a null id whose string_id<T>::is_null() must always return true.
@ TFLAG_HARVESTED
Definition: mapdata.h:303

References furn(), iexamine::none(), string_id< harvest_list >::NULL_ID(), wrapped_vehicle::pos, ter(), and TFLAG_HARVESTED.

Referenced by harvest_common(), and is_harvestable().

◆ get_harvest_names()

const std::set< std::string > & map::get_harvest_names ( const tripoint p) const

Returns names of the items that would be dropped.

Definition at line 1642 of file map.cpp.

1643{
1644 static const std::set<std::string> null_harvest_names = {};
1645 const auto furn_here = furn( pos );
1646 if( furn_here->examine != iexamine::none ) {
1647 if( furn_here->has_flag( TFLAG_HARVESTED ) ) {
1648 return null_harvest_names;
1649 }
1650
1651 return furn_here->get_harvest_names();
1652 }
1653
1654 const auto ter_here = ter( pos );
1655 if( ter_here->has_flag( TFLAG_HARVESTED ) ) {
1656 return null_harvest_names;
1657 }
1658
1659 return ter_here->get_harvest_names();
1660}

References furn(), iexamine::none(), wrapped_vehicle::pos, ter(), and TFLAG_HARVESTED.

Referenced by npc::find_item().

◆ get_known_connections()

uint8_t map::get_known_connections ( const tripoint p,
int  connect_group,
const std::map< tripoint, ter_id > &  override = {} 
) const

Definition at line 1568 of file map.cpp.

1570{
1571 auto &ch = access_cache( p.z );
1572 uint8_t val = 0;
1573 std::function<bool( const tripoint & )> is_memorized;
1574#ifdef TILES
1575 if( use_tiles ) {
1576 is_memorized =
1577 [&]( const tripoint & q ) {
1578 return !g->u.get_memorized_tile( getabs( q ) ).tile.empty();
1579 };
1580 } else {
1581#endif
1582 is_memorized =
1583 [&]( const tripoint & q ) {
1584 return g->u.get_memorized_symbol( getabs( q ) );
1585 };
1586#ifdef TILES
1587 }
1588#endif
1589
1590 const bool overridden = override.find( p ) != override.end();
1591 const bool is_transparent = ch.transparency_cache[p.x][p.y] > LIGHT_TRANSPARENCY_SOLID;
1592
1593 // populate connection information
1594 for( int i = 0; i < 4; ++i ) {
1595 tripoint neighbour = p + offsets[i];
1596 if( !inbounds( neighbour ) ) {
1597 continue;
1598 }
1599 const auto neighbour_override = override.find( neighbour );
1600 const bool neighbour_overridden = neighbour_override != override.end();
1601 // if there's some non-memory terrain to show at the neighboring tile
1602 const bool may_connect = neighbour_overridden ||
1603 get_visibility( ch.visibility_cache[neighbour.x][neighbour.y],
1605 // or if an actual center tile is transparent or next to a memorized tile
1606 ( !overridden && ( is_transparent || is_memorized( neighbour ) ) );
1607 if( may_connect ) {
1608 const ter_t &neighbour_terrain = neighbour_overridden ?
1609 neighbour_override->second.obj() : ter( neighbour ).obj();
1610 if( neighbour_terrain.connects_to( connect_group ) ) {
1611 val += 1 << i;
1612 }
1613 }
1614 }
1615
1616 return val;
1617}
bool use_tiles
Use tiles for display.
bool is_transparent(const tripoint &p) const
Returns whether the tile at p is transparent(you can look past it).
Definition: lightmap.cpp:655
level_cache & access_cache(int zlev)
Definition: map.cpp:8807
static constexpr std::array< point, 4 > offsets
Definition: point.h:361
bool connects_to(int test_connect_group) const
Definition: mapdata.h:435

References access_cache(), map_data_common_t::connects_to(), g, get_visibility(), get_visibility_variables_cache(), getabs(), inbounds(), is_transparent(), LIGHT_TRANSPARENCY_SOLID, int_id< T >::obj(), offsets, ter(), use_tiles, VIS_CLEAR, tripoint::x, tripoint::y, and tripoint::z.

Referenced by determine_wall_corner().

◆ get_neighbors()

std::array< std::pair< tripoint, maptile >, 8 > map::get_neighbors ( const tripoint p)
private

Definition at line 190 of file map_field.cpp.

191{
192 // Find out which edges are in the bubble
193 // Where possible, do just one bounds check for all the neighbors
194 const bool west = p.x > 0;
195 const bool north = p.y > 0;
196 const bool east = p.x < SEEX * my_MAPSIZE - 1;
197 const bool south = p.y < SEEY * my_MAPSIZE - 1;
198 return std::array< std::pair<tripoint, maptile>, 8 > { {
199 maptile_has_bounds( p + eight_horizontal_neighbors[0], west &&north ),
201 maptile_has_bounds( p + eight_horizontal_neighbors[2], east &&north ),
204 maptile_has_bounds( p + eight_horizontal_neighbors[5], west &&south ),
206 maptile_has_bounds( p + eight_horizontal_neighbors[7], east &&south ),
207 }
208 };
209}
std::pair< tripoint, maptile > maptile_has_bounds(const tripoint &p, bool bounds_checked)
Definition: map_field.cpp:180
static const std::array< tripoint, 8 > eight_horizontal_neighbors
Definition: point.h:379

References eight_horizontal_neighbors, maptile_has_bounds(), my_MAPSIZE, SEEX, SEEY, tripoint::x, and tripoint::y.

Referenced by process_fields_in_submap(), and spread_gas().

◆ get_nonant() [1/2]

size_t map::get_nonant ( const tripoint gridp) const
protected

Get the index of a submap pointer in the grid given by grid coordinates.

The grid coordinates must be valid: 0 <= x < my_MAPSIZE, same for y. Version with z-levels checks for z between -OVERMAP_DEPTH and OVERMAP_HEIGHT

Definition at line 8397 of file map.cpp.

8398{
8399 // There used to be a bounds check here
8400 // But this function is called a lot, so push it up if needed
8401 if( zlevels ) {
8402 const int indexz = gridp.z + OVERMAP_HEIGHT; // Can't be lower than 0
8403 return indexz + ( gridp.x + gridp.y * my_MAPSIZE ) * OVERMAP_LAYERS;
8404 } else {
8405 return gridp.x + gridp.y * my_MAPSIZE;
8406 }
8407}

References my_MAPSIZE, OVERMAP_HEIGHT, OVERMAP_LAYERS, tripoint::x, tripoint::y, tripoint::z, and zlevels.

Referenced by copy_grid(), fake_map::fake_map(), generate(), get_nonant(), get_submap_at_grid(), loadn(), and saven().

◆ get_nonant() [2/2]

size_t map::get_nonant ( point  gridp) const
inlineprotected

Definition at line 1830 of file map.h.

1830 {
1831 return get_nonant( { gridp, abs_sub.z } );
1832 }

References abs_sub, get_nonant(), and tripoint::z.

◆ get_pathfinding_cache()

pathfinding_cache & map::get_pathfinding_cache ( int  zlev) const
private

Definition at line 8857 of file map.cpp.

8858{
8859 return *pathfinding_caches[zlev + OVERMAP_DEPTH];
8860}

References OVERMAP_DEPTH, and pathfinding_caches.

Referenced by get_pathfinding_cache_ref(), set_pathfinding_cache_dirty(), and update_pathfinding_cache().

◆ get_pathfinding_cache_ref()

const pathfinding_cache & map::get_pathfinding_cache_ref ( int  zlev) const

Definition at line 8907 of file map.cpp.

8908{
8909 if( !inbounds_z( zlev ) ) {
8910 debugmsg( "Tried to get pathfinding cache for out of bounds z-level %d", zlev );
8912 }
8913 auto &cache = get_pathfinding_cache( zlev );
8914 if( cache.dirty ) {
8916 }
8917
8918 return cache;
8919}
void update_pathfinding_cache(int zlev) const
Definition: map.cpp:8921
bool inbounds_z(const int z) const
Definition: map.h:1611
pathfinding_cache & get_pathfinding_cache(int zlev) const
Definition: map.cpp:8857

References debugmsg, get_pathfinding_cache(), inbounds_z(), OVERMAP_DEPTH, pathfinding_caches, and update_pathfinding_cache().

Referenced by route(), and vertical_move_destination().

◆ get_radiation()

int map::get_radiation ( const tripoint p) const

Definition at line 4093 of file map.cpp.

4094{
4095 if( !inbounds( p ) ) {
4096 return 0;
4097 }
4098
4099 point l;
4100 submap *const current_submap = get_submap_at( p, l );
4101
4102 return current_submap->get_radiation( l );
4103}

References submap::get_radiation(), get_submap_at(), and inbounds().

Referenced by computer_session::action_geiger(), computer_session::action_irradiator(), check_art_charge_req(), relic_funcs::check_recharge_reqs(), editmap::draw_main_ui_overlay(), rad_scorch(), and Character::suffer_from_radiation().

◆ get_roof()

ter_id map::get_roof ( const tripoint p,
bool  allow_air 
) const
private

Definition at line 3163 of file map.cpp.

3164{
3165 // This function should not be called from the 2D mode
3166 // Just use t_dirt instead
3167 assert( zlevels );
3168
3169 if( p.z <= -OVERMAP_DEPTH ) {
3170 // Could be magma/"void" instead
3171 return t_rock_floor;
3172 }
3173
3174 const auto &ter_there = ter( p ).obj();
3175 const auto &roof = ter_there.roof;
3176 if( !roof ) {
3177 // No roof
3178 if( !allow_air ) {
3179 // TODO: Biomes? By setting? Forbid and treat as bug?
3180 if( p.z < 0 ) {
3181 return t_rock_floor_no_roof;
3182 }
3183
3184 return t_dirt;
3185 }
3186
3187 return t_open_air;
3188 }
3189
3190 ter_id new_ter = roof.id();
3191 if( new_ter == t_null ) {
3192 debugmsg( "map::get_new_floor: %d,%d,%d has invalid roof type %s",
3193 p.x, p.y, p.z, roof.c_str() );
3194 return t_dirt;
3195 }
3196
3197 if( p.z == -1 && new_ter == t_rock_floor ) {
3198 // HACK: A hack to work around not having a "solid earth" tile
3199 new_ter = t_dirt;
3200 }
3201
3202 return new_ter;
3203}
static const ter_str_id t_rock_floor_no_roof("t_rock_floor_no_roof")

References debugmsg, int_id< T >::id(), int_id< T >::obj(), OVERMAP_DEPTH, ter_t::roof, t_dirt, t_null, t_open_air, t_rock_floor, t_rock_floor_no_roof, ter(), tripoint::x, tripoint::y, tripoint::z, and zlevels.

Referenced by bash_ter_furn(), and bash_ter_success().

◆ get_signage()

std::string map::get_signage ( const tripoint p) const

Definition at line 4059 of file map.cpp.

4060{
4061 if( !inbounds( p ) ) {
4062 return "";
4063 }
4064
4065 point l;
4066 submap *const current_submap = get_submap_at( p, l );
4067
4068 return current_submap->get_signage( l );
4069}
std::string get_signage(point p) const
Definition: submap.cpp:161

References submap::get_signage(), get_submap_at(), and inbounds().

Referenced by game::extended_description(), game::place_player(), game::print_terrain_info(), and iexamine::sign().

◆ get_submap_at() [1/4]

◆ get_submap_at() [2/4]

submap * map::get_submap_at ( const tripoint p,
point offset_p 
) const
private

Get the submap pointer containing the specified position within the reality bubble.

The same as other get_submap_at, (p) must be valid (inbounds). Also writes the position within the submap to offset_p

Definition at line 8385 of file map.cpp.

8386{
8387 offset_p.x = p.x % SEEX;
8388 offset_p.y = p.y % SEEY;
8389 return get_submap_at( p );
8390}

References get_submap_at(), SEEX, SEEY, point::x, tripoint::x, point::y, and tripoint::y.

◆ get_submap_at() [3/4]

submap * map::get_submap_at ( point  p) const
inlineprivate

Definition at line 1802 of file map.h.

1802 {
1803 return get_submap_at( tripoint( p, abs_sub.z ) );
1804 }

References abs_sub, get_submap_at(), and tripoint::z.

◆ get_submap_at() [4/4]

submap * map::get_submap_at ( point  p,
point offset_p 
) const
inlineprivate

Definition at line 1811 of file map.h.

1811 {
1812 return get_submap_at( { p, abs_sub.z }, offset_p );
1813 }

References abs_sub, get_submap_at(), and tripoint::z.

◆ get_submap_at_grid() [1/2]

submap * map::get_submap_at_grid ( const tripoint gridp) const
private

Definition at line 8392 of file map.cpp.

8393{
8394 return getsubmap( get_nonant( gridp ) );
8395}

References get_nonant(), and getsubmap().

◆ get_submap_at_grid() [2/2]

◆ get_submaps_with_active_items()

const std::set< tripoint > & map::get_submaps_with_active_items ( ) const
inline

Definition at line 2003 of file map.h.

2003 {
2005 }

References submaps_with_active_items.

◆ get_temperature()

int map::get_temperature ( const tripoint p) const

Definition at line 4130 of file map.cpp.

4131{
4132 if( !inbounds( p ) ) {
4133 return 0;
4134 }
4135
4136 return get_submap_at( p )->get_temperature();
4137}
int get_temperature() const
Definition: submap.h:165

References get_submap_at(), submap::get_temperature(), and inbounds().

◆ get_ter_transforms_into()

ter_id map::get_ter_transforms_into ( const tripoint p) const

Definition at line 1665 of file map.cpp.

1666{
1667 return ter( p ).obj().transforms_into.id();
1668}
ter_str_id transforms_into
Definition: mapdata.h:470

References string_id< T >::id(), int_id< T >::obj(), ter(), and ter_t::transforms_into.

Referenced by iexamine::harvest_ter(), iexamine::harvest_ter_nectar(), and iexamine::tree_hickory().

◆ get_vehicle_zones()

std::vector< zone_data * > map::get_vehicle_zones ( int  zlev)

Definition at line 997 of file map.cpp.

998{
999 std::vector<zone_data *> veh_zones;
1000 bool rebuild = false;
1001 for( auto veh : get_cache( zlev ).zone_vehicles ) {
1002 if( veh->refresh_zones() ) {
1003 rebuild = true;
1004 }
1005 for( auto &zone : veh->loot_zones ) {
1006 veh_zones.emplace_back( &zone.second );
1007 }
1008 }
1009 if( rebuild ) {
1011 }
1012 return veh_zones;
1013}
static zone_manager & get_manager()
Definition: clzones.cpp:126
void cache_vzones()
Definition: clzones.cpp:624

References zone_manager::cache_vzones(), get_cache(), and zone_manager::get_manager().

Referenced by zone_manager::cache_vzones(), zone_manager::get_bottom_zone(), zone_manager::get_zone_at(), and zone_manager::get_zones().

◆ get_vehicles() [1/2]

◆ get_vehicles() [2/2]

VehicleList map::get_vehicles ( const tripoint start,
const tripoint end 
)

Definition at line 1038 of file map.cpp.

1039{
1040 const int chunk_sx = std::max( 0, ( start.x / SEEX ) - 1 );
1041 const int chunk_ex = std::min( my_MAPSIZE - 1, ( end.x / SEEX ) + 1 );
1042 const int chunk_sy = std::max( 0, ( start.y / SEEY ) - 1 );
1043 const int chunk_ey = std::min( my_MAPSIZE - 1, ( end.y / SEEY ) + 1 );
1044 const int chunk_sz = start.z;
1045 const int chunk_ez = end.z;
1046 VehicleList vehs;
1047
1048 for( int cx = chunk_sx; cx <= chunk_ex; ++cx ) {
1049 for( int cy = chunk_sy; cy <= chunk_ey; ++cy ) {
1050 for( int cz = chunk_sz; cz <= chunk_ez; ++cz ) {
1051 submap *current_submap = get_submap_at_grid( { cx, cy, cz } );
1052 for( const auto &elem : current_submap->vehicles ) {
1053 // Ensure the vehicle z-position is correct
1054 elem->sm_pos.z = cz;
1056 w.v = elem.get();
1057 w.pos = w.v->global_pos3();
1058 vehs.push_back( w );
1059 }
1060 }
1061 }
1062 }
1063
1064 return vehs;
1065}
tripoint pos
Definition: map.h:81
vehicle * v
Definition: map.h:82

References get_submap_at_grid(), vehicle::global_pos3(), my_MAPSIZE, wrapped_vehicle::pos, SEEX, SEEY, wrapped_vehicle::v, submap::vehicles, tripoint::x, tripoint::y, and tripoint::z.

◆ get_visibility()

visibility_type map::get_visibility ( lit_level  ll,
const visibility_variables cache 
) const

Definition at line 5723 of file map.cpp.

5725{
5726 switch( ll ) {
5727 case lit_level::DARK:
5728 // can't see this square at all
5729 if( cache.u_is_boomered ) {
5730 return VIS_BOOMER_DARK;
5731 } else {
5732 return VIS_DARK;
5733 }
5735 // can only tell that this square is bright
5736 if( cache.u_is_boomered ) {
5737 return VIS_BOOMER;
5738 } else {
5739 return VIS_LIT;
5740 }
5741
5742 case lit_level::LOW:
5743 // low light, square visible in monochrome
5744 case lit_level::LIT:
5745 // normal light
5746 case lit_level::BRIGHT:
5747 // bright light
5748 return VIS_CLEAR;
5749 case lit_level::BLANK:
5751 return VIS_HIDDEN;
5752 }
5753 return VIS_HIDDEN;
5754}
bool u_is_boomered
Definition: map.h:124

References BLANK, BRIGHT, BRIGHT_ONLY, DARK, LIT, LOW, MEMORIZED, visibility_variables::u_is_boomered, VIS_BOOMER, VIS_BOOMER_DARK, VIS_CLEAR, VIS_DARK, VIS_HIDDEN, and VIS_LIT.

Referenced by draw(), game::draw_look_around_cursor(), generate_weather_anim_frame(), get_known_connections(), and game::print_all_tile_info().

◆ get_visibility_variables_cache()

const visibility_variables & map::get_visibility_variables_cache ( ) const

Definition at line 5718 of file map.cpp.

5719{
5721}
visibility_variables visibility_variables_cache
Definition: map.h:1982

References visibility_variables_cache.

Referenced by draw(), generate_weather_anim_frame(), get_known_connections(), game::look_around(), live_view::show(), and editmap::update_view_with_help().

◆ get_wind_blockers()

std::tuple< maptile, maptile, maptile > map::get_wind_blockers ( const int &  winddirection,
const tripoint pos 
)

Definition at line 1894 of file map_field.cpp.

1896{
1897 static const std::array<std::pair<int, std::tuple< point, point, point >>, 9> outputs = {{
1898 { 330, std::make_tuple( point_east, point_north_east, point_south_east ) },
1899 { 301, std::make_tuple( point_south_east, point_east, point_south ) },
1900 { 240, std::make_tuple( point_south, point_south_west, point_south_east ) },
1901 { 211, std::make_tuple( point_south_west, point_west, point_south ) },
1902 { 150, std::make_tuple( point_west, point_north_west, point_south_west ) },
1903 { 121, std::make_tuple( point_north_west, point_north, point_west ) },
1904 { 60, std::make_tuple( point_north, point_north_west, point_north_east ) },
1905 { 31, std::make_tuple( point_north_east, point_east, point_north ) },
1906 { 0, std::make_tuple( point_east, point_north_east, point_south_east ) }
1907 }
1908 };
1909
1910 tripoint removepoint;
1911 tripoint removepoint2;
1912 tripoint removepoint3;
1913 for( const std::pair<int, std::tuple< point, point, point >> &val : outputs ) {
1914 if( winddirection >= val.first ) {
1915 removepoint = pos + std::get<0>( val.second );
1916 removepoint2 = pos + std::get<1>( val.second );
1917 removepoint3 = pos + std::get<2>( val.second );
1918 break;
1919 }
1920 }
1921
1922 const maptile remove_tile = maptile_at( removepoint );
1923 const maptile remove_tile2 = maptile_at( removepoint2 );
1924 const maptile remove_tile3 = maptile_at( removepoint3 );
1925 return std::make_tuple( remove_tile, remove_tile2, remove_tile3 );
1926}

References maptile_at(), point_east, point_north, point_north_east, point_north_west, point_south, point_south_east, point_south_west, and point_west.

Referenced by spread_gas().

◆ getabs() [1/2]

tripoint map::getabs ( const tripoint p) const

Translates local (to this map) coordinates of a square to global absolute coordinates.

Coordinates is in the system that is used by the ter/furn/i_at functions. Output is in the same scale, but in global system.

Definition at line 8335 of file map.cpp.

8336{
8337 return sm_to_ms_copy( abs_sub.xy() ) + p;
8338}

References abs_sub, sm_to_ms_copy(), and tripoint::xy().

Referenced by activity_on_turn_move_loot(), add_basecamp_storage_to_loot_zone_list(), add_item(), Character::add_known_trap(), jmapgen_zone::apply(), are_requirements_nearby(), game::autopilot_vehicles(), talk_function::basecamp_mission(), bash_ter_furn(), iexamine::bulletin_board(), butcher_corpse_activity(), can_do_activity_there(), iexamine::cardreader(), vehicle::autodrive_controller::check_drivable(), game::check_near_zone(), game::check_zone(), chop_plank_activity(), chop_tree_activity(), complete_construction(), construction_activity(), game::control_vehicle(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::discharge_real_power_source(), npc::do_pulp(), construct::done_digormine_stair(), construct::done_mine_upstair(), draw_maptile(), editmap::edit_mapgen(), iexamine::elevator(), fill_funnels(), find_auto_consume(), game::find_or_make_stairs(), find_refuel_spot_zone(), find_valid_teleporters_omt(), activity_handlers::forage_finish(), inventory::form_from_map(), furn_set(), generic_multi_activity_check_requirement(), generic_multi_activity_do(), generic_multi_activity_handler(), generic_multi_activity_locations(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::get_fake_tool(), get_known_connections(), zone_manager::get_point_set_loot(), getabs(), Character::global_square_location(), npc::go_to_omt_destination(), good_fishing_spot(), game::grabbed_furn_move(), grow_plant(), npc::guard_current_pos(), npc::handle_sound(), Character::knows_trap(), mine_activity(), npc::move(), perform_zone_activity_turn(), place_construction(), game::place_player(), basecamp::place_results(), game::place_vehicle_nearby(), iexamine::plant_seed(), game::pre_print_all_tile_info(), sounds::process_sounds(), plot_options::query_seed(), npc::reach_omt_destination(), remove_submap_turrets(), requirements_map(), zone_manager::rotate_zones(), conditional_t< T >::set_is_outside(), target_ui::set_last_target(), shoot(), iexamine::shrub_wildveggies(), smash(), spawn_monsters_submap_group(), debug_menu::spawn_nested_mapgen(), spread_gas(), ter_set(), tidy_activity(), vehicle::total_wind_epower_w(), translate_radius(), iexamine::trap(), update_suspension_cache(), use_charges_from_furn(), iexamine::use_furn_fake_item(), basecamp::validate_sort_points(), vehicle_activity(), vertical_move_destination(), iuse::weather_tool(), npc::worker_downtime(), and game::zones_manager().

◆ getabs() [2/2]

point map::getabs ( point  p) const
inline

Definition at line 1596 of file map.h.

1596 {
1597 return getabs( tripoint( p, abs_sub.z ) ).xy();
1598 }

References abs_sub, getabs(), tripoint::xy(), and tripoint::z.

◆ getlocal() [1/2]

tripoint map::getlocal ( const tripoint p) const

Inverse of getabs.

Definition at line 8340 of file map.cpp.

8341{
8342 return p - sm_to_ms_copy( abs_sub.xy() );
8343}

References abs_sub, sm_to_ms_copy(), and tripoint::xy().

Referenced by basecamp::abandon_camp(), activity_on_turn_move_loot(), zone_manager::add(), add_basecamp_storage_to_loot_zone_list(), grid_furn_transform_queue::apply(), talk_function::basecamp_mission(), activity_handlers::build_do_turn(), can_do_activity_there(), Character::check_outbounds_activity(), activity_handlers::chop_logs_finish(), activity_handlers::chop_planks_finish(), activity_handlers::chop_tree_do_turn(), activity_handlers::chop_tree_finish(), activity_handlers::churn_finish(), cleanup_tiles(), complete_construction(), veh_interact::complete_vehicle(), vehicle::autodrive_controller::compute_obstacles(), basecamp_action_components::consume_components(), deregister_vehicle_zone(), basecamp::distribute_food(), construct::done_digormine_stair(), construct::done_mine_upstair(), editmap::edit_mapgen(), npc::execute_action(), fetch_activity(), find_auto_consume(), game::find_or_make_stairs(), find_refuel_spot_zone(), activity_handlers::forage_finish(), basecamp::form_crafting_inventory(), inventory::form_from_zone(), generic_multi_activity_check_requirement(), generic_multi_activity_handler(), generic_multi_activity_locations(), item::get_cable_target(), zone_manager::get_point_set_loot(), getlocal(), npc::go_to_omt_destination(), npc::good_escape_direction(), Character::has_destination_activity(), activity_handlers::jackhammer_do_turn(), activity_handlers::jackhammer_finish(), activity_handlers::milk_finish(), npc::move(), npc::move_to(), map_cursor::operator tripoint(), perform_zone_activity_turn(), activity_handlers::pickaxe_do_turn(), activity_handlers::pickaxe_finish(), teleporter_list::place_avatar_overmap(), basecamp::place_results(), game::place_vehicle_nearby(), activity_handlers::plant_seed_finish(), vehicle_part::properties_to_item(), activity_handlers::pulp_do_turn(), plot_options::query_seed(), npc::reach_omt_destination(), target_ui::recalc_aim_turning_penalty(), npc::regen_ai_cache(), requirements_map(), zone_manager::revert_vzones(), rotate(), zone_manager::rotate_zones(), activity_handlers::shear_finish(), debug_menu::spawn_nested_mapgen(), tidy_activity(), activity_handlers::travel_do_turn(), target_ui::try_reacquire_target(), update_suspension_cache(), basecamp::validate_sort_points(), activity_handlers::vehicle_finish(), vertical_move_destination(), npc::worker_downtime(), and game::zones_manager().

◆ getlocal() [2/2]

point map::getlocal ( point  p) const
inline

Definition at line 1603 of file map.h.

1603 {
1604 return getlocal( tripoint( p, abs_sub.z ) ).xy();
1605 }

References abs_sub, getlocal(), tripoint::xy(), and tripoint::z.

◆ getmapsize()

int map::getmapsize ( ) const
inline

Definition at line 1620 of file map.h.

1620 {
1621 return my_MAPSIZE;
1622 }

References my_MAPSIZE.

Referenced by distribution_grid_tracker::load(), editmap::mapgen_preview(), and points_in_range().

◆ getsubmap()

submap * map::getsubmap ( size_t  grididx) const
private

Get the submap pointer with given index in grid, the index must be valid!

Definition at line 8355 of file map.cpp.

8356{
8357 if( grididx >= grid.size() ) {
8358 debugmsg( "Tried to access invalid grid index %d. Grid size: %d", grididx, grid.size() );
8359 return nullptr;
8360 }
8361 return grid[grididx];
8362}

References debugmsg, and grid.

Referenced by generate(), get_submap_at_grid(), and saven().

◆ graffiti_at()

const std::string & map::graffiti_at ( const tripoint p) const

Definition at line 7897 of file map.cpp.

7898{
7899 if( !inbounds( p ) ) {
7900 static const std::string empty_string;
7901 return empty_string;
7902 }
7903 point l;
7904 submap *const current_submap = get_submap_at( p, l );
7905 return current_submap->get_graffiti( l );
7906}
const std::string & get_graffiti(point p) const
Definition: submap.cpp:123

References submap::get_graffiti(), get_submap_at(), and inbounds().

Referenced by advanced_inv_area::init(), game::place_player(), game::print_graffiti_info(), and editmap::update_view_with_help().

◆ grow_plant()

void map::grow_plant ( const tripoint p)
protected

Try to grow a harvestable plant to the next stage(s).

Definition at line 7225 of file map.cpp.

7226{
7227 const auto &furn = this->furn( p ).obj();
7228 if( !furn.has_flag( "PLANT" ) ) {
7229 return;
7230 }
7231 // Can't use item_stack::only_item() since there might be fertilizer
7232 map_stack items = i_at( p );
7233 map_stack::iterator seed = std::find_if( items.begin(), items.end(), []( const item & it ) {
7234 return it.is_seed();
7235 } );
7236
7237 if( seed == items.end() ) {
7238 // No seed there anymore, we don't know what kind of plant it was.
7239 // TODO: Fix point types
7240 const oter_id ot = overmap_buffer.ter( project_to<coords::omt>( tripoint_abs_ms( getabs( p ) ) ) );
7241 dbg( DL::Error ) << "a planted item at " << p
7242 << " (within overmap terrain " << ot.id().str() << ") has no seed data";
7243 i_clear( p );
7244 furn_set( p, f_null );
7245 return;
7246 }
7247 const time_duration plantEpoch = seed->get_plant_epoch();
7248 if( seed->age() >= plantEpoch * furn.plant->growth_multiplier &&
7249 !furn.has_flag( "GROWTH_HARVEST" ) ) {
7250 if( seed->age() < plantEpoch * 2 ) {
7251 if( has_flag_furn( "GROWTH_SEEDLING", p ) ) {
7252 return;
7253 }
7254
7255 // Remove fertilizer if any
7256 map_stack::iterator fertilizer = std::find_if( items.begin(), items.end(), []( const item & it ) {
7257 return it.has_flag( "FERTILIZER" );
7258 } );
7259 if( fertilizer != items.end() ) {
7260 items.erase( fertilizer );
7261 }
7262
7263 rotten_item_spawn( *seed, p );
7264 furn_set( p, furn_str_id( furn.plant->transform ) );
7265 } else if( seed->age() < plantEpoch * 3 * furn.plant->growth_multiplier ) {
7266 if( has_flag_furn( "GROWTH_MATURE", p ) ) {
7267 return;
7268 }
7269
7270 // Remove fertilizer if any
7271 map_stack::iterator fertilizer = std::find_if( items.begin(), items.end(), []( const item & it ) {
7272 return it.has_flag( "FERTILIZER" );
7273 } );
7274 if( fertilizer != items.end() ) {
7275 items.erase( fertilizer );
7276 }
7277
7278 rotten_item_spawn( *seed, p );
7279 //You've skipped the seedling stage so roll monsters twice
7280 if( !has_flag_furn( "GROWTH_SEEDLING", p ) ) {
7281 rotten_item_spawn( *seed, p );
7282 }
7283 furn_set( p, furn_str_id( furn.plant->transform ) );
7284 } else {
7285 //You've skipped two stages so roll monsters two times
7286 if( has_flag_furn( "GROWTH_SEEDLING", p ) ) {
7287 rotten_item_spawn( *seed, p );
7288 rotten_item_spawn( *seed, p );
7289 //One stage change
7290 } else if( has_flag_furn( "GROWTH_MATURE", p ) ) {
7291 rotten_item_spawn( *seed, p );
7292 //Goes from seed to harvest in one check
7293 } else {
7294 rotten_item_spawn( *seed, p );
7295 rotten_item_spawn( *seed, p );
7296 rotten_item_spawn( *seed, p );
7297 }
7298 furn_set( p, furn_str_id( furn.plant->transform ) );
7299 }
7300 }
7301}
iterator erase(const_iterator it) override
Definition: map.cpp:152
void rotten_item_spawn(const item &item, const tripoint &p)
Checks to see if the item that is rotting away generates a creature when it does.
Definition: map.cpp:7177
string_id< furn_t > furn_str_id
Definition: type_id.h:65

References item_stack::begin(), dbg, item_stack::end(), map_stack::erase(), Error, f_null, furn(), furn_set(), getabs(), has_flag_furn(), i_at(), i_clear(), int_id< T >::id(), int_id< T >::obj(), overmap_buffer, rotten_item_spawn(), iuse::seed(), string_id< T >::str(), and overmapbuffer::ter().

Referenced by actualize().

◆ has_adjacent_furniture_with()

bool map::has_adjacent_furniture_with ( const tripoint p,
const std::function< bool(const furn_t &)> &  filter 
)

Returns true if there is furniture for which filter returns true in a 1 tile radius of p.

Pass return_true<furn_t> to detect all adjacent furniture.

Parameters
pthe location to check at
filterwhat to filter the furniture by.

Definition at line 2810 of file map.cpp.

2812{
2813 for( const tripoint &adj : points_in_radius( p, 1 ) ) {
2814 if( has_furn( adj ) && filter( furn( adj ).obj() ) ) {
2815 return true;
2816 }
2817 }
2818
2819 return false;
2820}

References furn(), has_furn(), and points_in_radius().

◆ has_flag() [1/4]

bool map::has_flag ( const std::string &  flag,
const tripoint p 
) const

Definition at line 2351 of file map.cpp.

2352{
2353 return has_flag_ter_or_furn( flag, p ); // Does bound checking
2354}

References has_flag_ter_or_furn().

Referenced by accessible_items(), Character::activate_bionic(), add_item(), add_item_or_charges(), npc::assess_danger(), bash(), bash_ter_furn(), bash_ter_success(), start_location::burn(), activity_handlers::burrow_finish(), game::butcher(), can_do_activity_there(), can_examine_at(), can_move_vertical_at(), can_put_items_ter_furn(), monster::can_reach_to(), iexamine::chainfence(), construct::check_empty(), vehicle::check_falling_or_floating(), construct::check_support(), chop_tree_activity(), climb_difficulty(), close_door(), doors::close_door(), collapse_at(), collapse_check(), consider_butchery(), iexamine::curtains(), displace_water(), character_funcs::do_pause(), dont_draw_lower_floor(), iexamine::door_peephole(), draw_lab(), drop_everything(), drop_or_embed_projectile(), iexamine::elevator(), explosion_handler::emp_blast(), game::examine(), computer_session::failure_shutdown(), features(), find_closest_stair(), find_furnitures_or_vparts_with_flag_in_radius(), game::find_or_make_stairs(), flammable_items_at(), game::fling_creature(), game::forced_door_closing(), generic_multi_activity_do(), game::get_dangerous_tile(), get_fire_fuel_string(), game::get_fishable_locations(), overmap_ui::get_overmap_path_to(), game::grabbed_furn_move(), has_flag(), has_nearby_chair(), has_nearby_table(), haul(), hit_with_fire(), in_spell_aoe(), vehicle::interact_with(), is_divable(), game::is_empty(), is_flammable(), is_water_shallow_current(), game::knockback(), mine_activity(), mop_spills(), monster::move(), avatar_action::move(), npc::move_to(), move_vehicle(), game::moving_vehicle_dismount(), MapExtras::mx_minefield(), item::on_drop(), open(), open_door(), vehicle::part_collision(), activity_handlers::pickaxe_finish(), game::place_player(), game::print_fields_info(), game::print_items_info(), item::process_extinguish(), process_fields_in_submap(), item::process_litcig(), spell_effect::projectile_attack(), propagate_field(), propagate_suspension_check(), avatar_action::ramp_move(), rate_location(), route(), area_expander::run(), Character::run_cost(), conditional_t< T >::set_is_outside(), vehicle::shift_zlevel(), shoot(), spawn_an_item(), spawn_items(), spell_effect::spell_effect_cone(), fungal_effects::spread_fungus(), fungal_effects::spread_fungus_one_tile(), monster::stumble(), Character::suffer_from_other_mutations(), avatar_action::swim(), test_passable(), game::update_stair_monsters(), editmap::update_view_with_help(), place_trap_actor::use(), deploy_tent_actor::use(), use_charges_from_furn(), game::use_computer(), game::vertical_move(), vertical_move_destination(), game::walk_move(), water_from(), and npc::worker_downtime().

◆ has_flag() [2/4]

bool map::has_flag ( const std::string &  flag,
point  p 
) const
inline

Definition at line 903 of file map.h.

903 {
904 return has_flag( flag, tripoint( p, abs_sub.z ) );
905 }

References abs_sub, has_flag(), and tripoint::z.

◆ has_flag() [3/4]

bool map::has_flag ( ter_bitflags  flag,
const tripoint p 
) const

Definition at line 2394 of file map.cpp.

2395{
2396 return has_flag_ter_or_furn( flag, p ); // Does bound checking
2397}

References has_flag_ter_or_furn().

◆ has_flag() [4/4]

bool map::has_flag ( ter_bitflags  flag,
point  p 
) const
inline

Definition at line 938 of file map.h.

938 {
939 return has_flag( flag, tripoint( p, abs_sub.z ) );
940 }

References abs_sub, has_flag(), and tripoint::z.

◆ has_flag_furn() [1/4]

◆ has_flag_furn() [2/4]

bool map::has_flag_furn ( const std::string &  flag,
point  p 
) const
inline

Definition at line 923 of file map.h.

923 {
924 return has_flag_furn( flag, tripoint( p, abs_sub.z ) );
925 }

References abs_sub, has_flag_furn(), and tripoint::z.

◆ has_flag_furn() [3/4]

bool map::has_flag_furn ( ter_bitflags  flag,
const tripoint p 
) const

Definition at line 2404 of file map.cpp.

2405{
2406 return furn( p ).obj().has_flag( flag );
2407}

References furn(), map_data_common_t::has_flag(), and int_id< T >::obj().

◆ has_flag_furn() [4/4]

bool map::has_flag_furn ( ter_bitflags  flag,
point  p 
) const
inline

Definition at line 948 of file map.h.

948 {
949 return has_flag_furn( flag, tripoint( p, abs_sub.z ) );
950 }

References abs_sub, has_flag_furn(), and tripoint::z.

◆ has_flag_furn_or_vpart()

bool map::has_flag_furn_or_vpart ( const std::string &  flag,
const tripoint p 
) const

Definition at line 2415 of file map.cpp.

2416{
2417 return has_flag_furn( flag, p ) || has_flag_vpart( flag, p );
2418}
bool has_flag_vpart(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2409

References has_flag_furn(), and has_flag_vpart().

Referenced by find_furnitures_or_vparts_with_flag_in_radius(), activity_handlers::operation_do_turn(), and operator_present().

◆ has_flag_ter() [1/4]

◆ has_flag_ter() [2/4]

bool map::has_flag_ter ( const std::string &  flag,
point  p 
) const
inline

Definition at line 918 of file map.h.

918 {
919 return has_flag_ter( flag, tripoint( p, abs_sub.z ) );
920 }

References abs_sub, has_flag_ter(), and tripoint::z.

◆ has_flag_ter() [3/4]

bool map::has_flag_ter ( ter_bitflags  flag,
const tripoint p 
) const

Definition at line 2399 of file map.cpp.

2400{
2401 return ter( p ).obj().has_flag( flag );
2402}

References map_data_common_t::has_flag(), int_id< T >::obj(), and ter().

◆ has_flag_ter() [4/4]

bool map::has_flag_ter ( ter_bitflags  flag,
point  p 
) const
inline

Definition at line 943 of file map.h.

943 {
944 return has_flag_ter( flag, tripoint( p, abs_sub.z ) );
945 }

References abs_sub, has_flag_ter(), and tripoint::z.

◆ has_flag_ter_or_furn() [1/4]

◆ has_flag_ter_or_furn() [2/4]

bool map::has_flag_ter_or_furn ( const std::string &  flag,
point  p 
) const
inline

Definition at line 932 of file map.h.

932 {
933 return has_flag_ter_or_furn( flag, tripoint( p, abs_sub.z ) );
934 }

References abs_sub, has_flag_ter_or_furn(), and tripoint::z.

◆ has_flag_ter_or_furn() [3/4]

bool map::has_flag_ter_or_furn ( ter_bitflags  flag,
const tripoint p 
) const

Definition at line 2420 of file map.cpp.

2421{
2422 if( !inbounds( p ) ) {
2423 return false;
2424 }
2425
2426 point l;
2427 submap *const current_submap = get_submap_at( p, l );
2428
2429 return current_submap && //FIXME: can be null during mapgen
2430 ( current_submap->get_ter( l ).obj().has_flag( flag ) ||
2431 current_submap->get_furn( l ).obj().has_flag( flag ) );
2432}

References submap::get_furn(), get_submap_at(), submap::get_ter(), map_data_common_t::has_flag(), inbounds(), and int_id< T >::obj().

◆ has_flag_ter_or_furn() [4/4]

bool map::has_flag_ter_or_furn ( ter_bitflags  flag,
point  p 
) const
inline

Definition at line 953 of file map.h.

953 {
954 return has_flag_ter_or_furn( flag, tripoint( p, abs_sub.z ) );
955 }

References abs_sub, has_flag_ter_or_furn(), and tripoint::z.

◆ has_flag_vpart()

bool map::has_flag_vpart ( const std::string &  flag,
const tripoint p 
) const

Definition at line 2409 of file map.cpp.

2410{
2411 const optional_vpart_position vp = veh_at( p );
2412 return static_cast<bool>( vp.part_with_feature( flag, true ) );
2413}

References optional_vpart_position::part_with_feature(), and veh_at().

Referenced by has_flag_furn_or_vpart().

◆ has_floor()

bool map::has_floor ( const tripoint p) const

◆ has_floor_or_support()

bool map::has_floor_or_support ( const tripoint p) const

Definition at line 2097 of file map.cpp.

2098{
2099 const tripoint below( p.xy(), p.z - 1 );
2100 return !valid_move( p, below, false, true );
2101}

References valid_move(), tripoint::xy(), and tripoint::z.

Referenced by monster::move(), game::print_terrain_info(), avatar_action::ramp_move(), reachable_flood_steps(), smash(), and game::vertical_move().

◆ has_furn() [1/2]

◆ has_furn() [2/2]

bool map::has_furn ( point  p) const
inline

Definition at line 788 of file map.h.

788 {
789 return has_furn( tripoint( p, abs_sub.z ) );
790 }

References abs_sub, has_furn(), and tripoint::z.

◆ has_graffiti_at()

bool map::has_graffiti_at ( const tripoint p) const

Definition at line 7908 of file map.cpp.

7909{
7910 if( !inbounds( p ) ) {
7911 return false;
7912 }
7913 point l;
7914 submap *const current_submap = get_submap_at( p, l );
7915 return current_submap->has_graffiti( l );
7916}
bool has_graffiti(point p) const
Definition: submap.cpp:118

References get_submap_at(), submap::has_graffiti(), and inbounds().

Referenced by editmap::draw_main_ui_overlay(), advanced_inv_area::init(), game::place_player(), game::print_graffiti_info(), and editmap::update_view_with_help().

◆ has_items()

bool map::has_items ( const tripoint p) const

Checks for existence of items.

Faster than i_at(p).empty

Definition at line 4830 of file map.cpp.

4831{
4832 if( !inbounds( p ) ) {
4833 return false;
4834 }
4835
4836 point l;
4837 submap *const current_submap = get_submap_at( p, l );
4838
4839 return !current_submap->get_items( l ).empty();
4840}

References submap::get_items(), get_submap_at(), and inbounds().

Referenced by Character::activate_bionic(), bash_items(), can_do_activity_there(), can_examine_at(), can_pickup_at(), drop_furniture(), drop_items(), flammable_items_at(), inventory::form_from_map(), generate_lightmap(), has_clear_path_to_pickup_items(), haul(), iuse::note_bionics(), npc::pick_up_item(), game::place_player(), sees_some_items(), and smash_items().

◆ has_nearby_chair()

bool map::has_nearby_chair ( const tripoint p,
int  radius = 1 
)

Check whether a chair or vehicle seat is nearby.

Definition at line 2849 of file map.cpp.

2850{
2851 for( const tripoint &pt : points_in_radius( p, radius ) ) {
2852 const optional_vpart_position vp = veh_at( pt );
2853 if( has_flag( "CAN_SIT", pt ) ) {
2854 return true;
2855 }
2856 if( vp && vp->vehicle().has_part( "SEAT" ) ) {
2857 return true;
2858 }
2859 }
2860 return false;
2861}

References has_flag(), points_in_radius(), and veh_at().

◆ has_nearby_fire()

bool map::has_nearby_fire ( const tripoint p,
int  radius = 1 
)

Definition at line 2822 of file map.cpp.

2823{
2824 for( const tripoint &pt : points_in_radius( p, radius ) ) {
2825 if( get_field( pt, fd_fire ) != nullptr ) {
2826 return true;
2827 }
2828 if( has_flag_ter_or_furn( "USABLE_FIRE", pt ) ) {
2829 return true;
2830 }
2831 }
2832 return false;
2833}

References fd_fire, get_field(), has_flag_ter_or_furn(), and points_in_radius().

Referenced by iexamine::fireplace(), and inventory::form_from_map().

◆ has_nearby_table()

bool map::has_nearby_table ( const tripoint p,
int  radius = 1 
)

Check whether a table/workbench/vehicle kitchen or other flat surface is nearby that could be used for crafting or eating.

Definition at line 2835 of file map.cpp.

2836{
2837 for( const tripoint &pt : points_in_radius( p, radius ) ) {
2838 const optional_vpart_position vp = veh_at( p );
2839 if( has_flag( "FLAT_SURF", pt ) ) {
2840 return true;
2841 }
2842 if( vp && ( vp->vehicle().has_part( "KITCHEN" ) || vp->vehicle().has_part( "FLAT_SURF" ) ) ) {
2843 return true;
2844 }
2845 }
2846 return false;
2847}

References has_flag(), points_in_radius(), and veh_at().

Referenced by can_do_activity_there(), and consider_butchery().

◆ has_zlevels()

◆ hit_with_acid()

bool map::hit_with_acid ( const tripoint p)

Definition at line 3888 of file map.cpp.

3889{
3890 if( passable( p ) ) {
3891 return false; // Didn't hit the tile!
3892 }
3893 const ter_id t = ter( p );
3894 if( t == t_wall_glass || t == t_wall_glass_alarm ||
3895 t == t_vat ) {
3896 ter_set( p, t_floor );
3897 } else if( t == t_door_c || t == t_door_locked || t == t_door_locked_peep ||
3898 t == t_door_locked_alarm ) {
3899 if( one_in( 3 ) ) {
3900 ter_set( p, t_door_b );
3901 }
3902 } else if( t == t_door_bar_c || t == t_door_bar_o || t == t_door_bar_locked || t == t_bars ||
3903 t == t_reb_cage ) {
3904 ter_set( p, t_floor );
3905 add_msg( m_warning, _( "The metal bars melt!" ) );
3906 } else if( t == t_door_b ) {
3907 if( one_in( 4 ) ) {
3908 ter_set( p, t_door_frame );
3909 } else {
3910 return false;
3911 }
3912 } else if( t == t_window || t == t_window_alarm || t == t_window_no_curtains ) {
3913 ter_set( p, t_window_empty );
3914 } else if( t == t_wax ) {
3915 ter_set( p, t_floor_wax );
3916 } else if( t == t_gas_pump || t == t_gas_pump_smashed ) {
3917 return false;
3918 } else if( t == t_card_science || t == t_card_military || t == t_card_industrial ) {
3920 }
3921 return true;
3922}
@ m_warning
Definition: enums.h:264
ter_id t_card_industrial
Definition: mapdata.cpp:724
ter_id t_floor_wax
Definition: mapdata.cpp:687
ter_id t_reb_cage
Definition: mapdata.cpp:656
ter_id t_card_military
Definition: mapdata.cpp:724
ter_id t_door_bar_locked
Definition: mapdata.cpp:665
ter_id t_window_alarm
Definition: mapdata.cpp:670
ter_id t_door_bar_o
Definition: mapdata.cpp:665
ter_id t_gas_pump
Definition: mapdata.cpp:700
ter_id t_wall_glass_alarm
Definition: mapdata.cpp:651
ter_id t_card_reader_broken
Definition: mapdata.cpp:724
ter_id t_gas_pump_smashed
Definition: mapdata.cpp:700
ter_id t_door_locked_peep
Definition: mapdata.cpp:659
ter_id t_door_bar_c
Definition: mapdata.cpp:665
ter_id t_door_frame
Definition: mapdata.cpp:660
ter_id t_vat
Definition: mapdata.cpp:712
ter_id t_window_no_curtains
Definition: mapdata.cpp:674
ter_id t_wax
Definition: mapdata.cpp:687
ter_id t_window_empty
Definition: mapdata.cpp:670
ter_id t_door_b
Definition: mapdata.cpp:658

References _, add_msg(), m_warning, one_in(), passable(), t_bars, t_card_industrial, t_card_military, t_card_reader_broken, t_card_science, t_door_b, t_door_bar_c, t_door_bar_locked, t_door_bar_o, t_door_c, t_door_frame, t_door_locked, t_door_locked_alarm, t_door_locked_peep, t_floor, t_floor_wax, t_gas_pump, t_gas_pump_smashed, t_reb_cage, t_vat, t_wall_glass, t_wall_glass_alarm, t_wax, t_window, t_window_alarm, t_window_empty, t_window_no_curtains, ter(), and ter_set().

◆ hit_with_fire()

bool map::hit_with_fire ( const tripoint p)

Definition at line 3925 of file map.cpp.

3926{
3927 if( passable( p ) ) {
3928 return false; // Didn't hit the tile!
3929 }
3930
3931 // non passable but flammable terrain, set it on fire
3932 if( has_flag( "FLAMMABLE", p ) || has_flag( "FLAMMABLE_ASH", p ) ) {
3933 add_field( p, fd_fire, 3 );
3934 }
3935 return true;
3936}

References add_field(), fd_fire, has_flag(), and passable().

Referenced by mattack::flame().

◆ hoist_submap_camp()

basecamp map::hoist_submap_camp ( const tripoint p)

Definition at line 5646 of file map.cpp.

5647{
5648 basecamp *pcamp = get_submap_at( p )->camp.get();
5649 return pcamp ? *pcamp : basecamp();
5650}
std::unique_ptr< basecamp > camp
Definition: submap.h:220

References submap::camp, and get_submap_at().

Referenced by game::validate_camps().

◆ i_at() [1/2]

map_stack map::i_at ( const tripoint p)

Definition at line 4149 of file map.cpp.

4150{
4151 if( !inbounds( p ) ) {
4152 nulitems.clear();
4153 return map_stack{ &nulitems, p, this };
4154 }
4155
4156 point l;
4157 submap *const current_submap = get_submap_at( p, l );
4158
4159 return map_stack{ &current_submap->get_items( l ), p, this };
4160}
static cata::colony< item > nulitems
Definition: map.cpp:140

References submap::get_items(), get_submap_at(), inbounds(), and nulitems.

Referenced by computer_session::action_blood_anal(), computer_session::action_conveyor(), computer_session::action_data_anal(), computer_session::action_irradiator(), computer_session::action_list_bionics(), computer_session::action_sample(), Character::activate_bionic(), activity_on_turn_move_loot(), add_item_or_charges(), advanced_inventory_pane::add_items_from_area(), iexamine::aggie_plant(), apply_camp_ownership(), apply_faction_ownership(), iexamine::arcfurnace_empty(), iexamine::arcfurnace_full(), are_requirements_nearby(), iexamine::autoclave_full(), character_funcs::base_comfort_value(), bash_furn_success(), bash_items(), board_up(), MapExtras::burned_ground_parser(), game::butcher(), butcher_corpse_activity(), can_butcher_at(), can_do_activity_there(), iexamine::can_fertilize(), advanced_inventory::change_square(), construct::check_empty(), chop_plank_activity(), doors::close_door(), complete_construction(), iuse::directional_antenna(), iexamine::dirtmound(), displace_items_except_one_liquid(), basecamp::distribute_food(), construct::done_grave(), drop_furniture(), drop_items(), editmap::edit_itm(), iexamine::elevator(), explosion_handler::emp_blast(), game::examine(), computer_session::failure_destroy_blood(), computer_session::failure_destroy_data(), farm_action(), iexamine::fertilize_plant(), fetch_activity(), talk_function::field_harvest(), fill_funnels(), activity_handlers::fill_liquid_do_turn(), find_auto_consume(), npc::find_corpse_to_pulp(), npc::find_item(), game::find_nearby_items(), flammable_items_at(), Character::floor_item_warmth(), game::forced_door_closing(), basecamp::form_crafting_inventory(), inventory::form_from_map(), free_volume(), fromPumpFuel(), furnname(), iexamine::fvat_empty(), iexamine::fvat_full(), iexamine::gaspump(), generate_lightmap(), generic_multi_activity_locations(), advanced_inv_area::get_container(), player::get_eligible_containers_for_crafting(), advanced_inv_area::get_item_count(), iexamine::getNearFilledGasTank(), game::grabbed_furn_move(), grow_plant(), liquid_handler::handle_liquid_from_ground(), iexamine::harvest_plant(), i_at(), i_rem(), Character::is_snuggling(), activity_handlers::jackhammer_finish(), iexamine::keg(), iexamine::kiln_empty(), iexamine::kiln_full(), advanced_inventory_pane::load_settings(), activity_handlers::longsalvage_finish(), talk_function::loot_building(), max_volume(), mill_activate(), iexamine::mill_finalize(), mop_spills(), advanced_inventory::move_all_items(), MapExtras::mx_supplydrop(), iuse::note_bionics(), om_harvest_itm(), iexamine::pedestal_temple(), iexamine::pedestal_wyrm(), tutorial_game::per_turn(), npc::pick_up_item_map(), activity_handlers::pickaxe_finish(), game::place_player(), iexamine::pour_into_keg(), firestarter_actor::prep_firestarter_use(), game::print_items_info(), process_fields_in_submap(), process_items_in_submap(), produce_sap(), activity_handlers::pulp_do_turn(), iexamine::quern_examine(), plot_options::query_seed(), iexamine::recycle_compactor(), iexamine::reload_furniture(), requirements_map(), rod_fish(), npc::see_item_say_smth(), serialize_liquid_source(), iexamine::shrub_wildveggies(), smash(), smash_items(), smoker_activate(), smoker_finalize(), iexamine::smoker_options(), spell_move(), fungal_effects::spread_fungus_one_tile(), game::start_hauling(), basecamp::start_relay_hide_site(), stored_volume(), tidy_activity(), tinder_at(), iexamine::toilet(), iexamine::toPumpFuel(), iexamine::tree_maple_tapped(), try_fuel_fire(), editmap::update_view_with_help(), enzlave_actor::use(), use_amount_square(), use_charges(), use_charges_from_furn(), iexamine::use_furn_fake_item(), and iexamine::vending().

◆ i_at() [2/2]

map_stack map::i_at ( point  p)
inline

Definition at line 1179 of file map.h.

1179 {
1180 return i_at( tripoint( p, abs_sub.z ) );
1181 }

References abs_sub, i_at(), and tripoint::z.

◆ i_clear() [1/2]

void map::i_clear ( const tripoint p)

Definition at line 4187 of file map.cpp.

4188{
4189 point l;
4190 submap *const current_submap = get_submap_at( p, l );
4191
4192 for( item &it : current_submap->get_items( l ) ) {
4193 // remove from the active items cache (if it isn't there does nothing)
4194 current_submap->active_items.remove( &it );
4195 }
4196 if( current_submap->active_items.empty() ) {
4197 submaps_with_active_items.erase( tripoint( abs_sub.x + p.x / SEEX, abs_sub.y + p.y / SEEY, p.z ) );
4198 }
4199
4200 current_submap->set_lum( l, 0 );
4201 current_submap->get_items( l ).clear();
4202}
void remove(const item *it)
Removes the item if it is in the cache.
void set_lum(point p, uint8_t luminance)
Definition: submap.h:125

References abs_sub, submap::active_items, active_item_cache::empty(), submap::get_items(), get_submap_at(), active_item_cache::remove(), SEEX, SEEY, submap::set_lum(), submaps_with_active_items, tripoint::x, tripoint::y, and tripoint::z.

Referenced by computer_session::action_conveyor(), iexamine::aggie_plant(), jmapgen_terrain::apply(), iexamine::arcfurnace_empty(), board_up(), doors::close_door(), MapExtras::dead_vegetation_parser(), basecamp::distribute_food(), draw_lab(), drop_furniture(), drop_items(), computer_session::failure_destroy_blood(), computer_session::failure_destroy_data(), farm_action(), iexamine::fertilize_plant(), talk_function::field_harvest(), iexamine::fvat_empty(), iexamine::fvat_full(), game::grabbed_furn_move(), grow_plant(), iexamine::harvest_plant(), i_clear(), iexamine::keg(), iexamine::kiln_empty(), mapgen_lake_shore(), om_harvest_itm(), iexamine::pedestal_temple(), iexamine::pedestal_wyrm(), rad_scorch(), and iexamine::tree_maple_tapped().

◆ i_clear() [2/2]

void map::i_clear ( point  p)
inline

Definition at line 1184 of file map.h.

1184 {
1185 i_clear( tripoint( p, abs_sub.z ) );
1186 }

References abs_sub, i_clear(), and tripoint::z.

◆ i_rem() [1/4]

void map::i_rem ( const tripoint p,
item it 
)

Definition at line 4178 of file map.cpp.

4179{
4180 map_stack map_items = i_at( p );
4182 if( iter != map_items.end() ) {
4183 i_rem( p, iter );
4184 }
4185}
iterator get_iterator_from_pointer(item *it)
Definition: item_stack.cpp:68
map_stack::iterator i_rem(const tripoint &p, map_stack::const_iterator it)
Definition: map.cpp:4162

References item_stack::end(), item_stack::get_iterator_from_pointer(), i_at(), and i_rem().

◆ i_rem() [2/4]

map_stack::iterator map::i_rem ( const tripoint p,
map_stack::const_iterator  it 
)

Definition at line 4162 of file map.cpp.

4163{
4164 point l;
4165 submap *const current_submap = get_submap_at( p, l );
4166
4167 // remove from the active items cache (if it isn't there does nothing)
4168 current_submap->active_items.remove( &*it );
4169 if( current_submap->active_items.empty() ) {
4170 submaps_with_active_items.erase( tripoint( abs_sub.x + p.x / SEEX, abs_sub.y + p.y / SEEY, p.z ) );
4171 }
4172
4173 current_submap->update_lum_rem( l, *it );
4174
4175 return current_submap->get_items( l ).erase( it );
4176}
void update_lum_rem(point p, const item &i)
Definition: submap.cpp:56

References abs_sub, submap::active_items, active_item_cache::empty(), submap::get_items(), get_submap_at(), active_item_cache::remove(), SEEX, SEEY, submaps_with_active_items, submap::update_lum_rem(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by computer_session::action_irradiator(), chop_plank_activity(), delete_cyborg_item(), iexamine::elevator(), map_stack::erase(), iexamine::fvat_full(), i_rem(), mill_activate(), move_item(), om_set_hide_site(), rcdrive(), remove_rotten_items(), smash_items(), and smoker_activate().

◆ i_rem() [3/4]

map_stack::iterator map::i_rem ( point  location,
map_stack::const_iterator  it 
)
inline

Definition at line 1190 of file map.h.

1190 {
1191 return i_rem( tripoint( location, abs_sub.z ), it );
1192 }

References abs_sub, i_rem(), and tripoint::z.

◆ i_rem() [4/4]

void map::i_rem ( point  p,
item it 
)
inline

Definition at line 1194 of file map.h.

1194 {
1195 i_rem( tripoint( p, abs_sub.z ), it );
1196 }

References abs_sub, i_rem(), and tripoint::z.

◆ impassable() [1/2]

◆ impassable() [2/2]

bool map::impassable ( point  p) const
inline

Definition at line 566 of file map.h.

566 {
567 return !passable( p );
568 }

References passable().

◆ impassable_ter_furn()

bool map::impassable_ter_furn ( const tripoint p) const

Definition at line 1886 of file map.cpp.

1887{
1888 return !passable_ter_furn( p );
1889}
bool passable_ter_furn(const tripoint &p) const
Definition: map.cpp:1891

References passable_ter_furn().

Referenced by vehicle::check_heli_ascend(), vehicle::check_heli_descend(), climb_difficulty(), displace_water(), and vehicle::part_collision().

◆ inbounds() [1/2]

bool map::inbounds ( const tripoint p) const
virtual

Reimplemented in tinymap.

Definition at line 7831 of file map.cpp.

7832{
7833 static constexpr tripoint map_boundary_min( 0, 0, -OVERMAP_DEPTH );
7834 static constexpr tripoint map_boundary_max( MAPSIZE_Y, MAPSIZE_X, OVERMAP_HEIGHT + 1 );
7835
7836 static constexpr half_open_cuboid<tripoint> map_boundaries(
7837 map_boundary_min, map_boundary_max );
7838
7839 return map_boundaries.contains( p );
7840}

References half_open_cuboid< Tripoint, >::contains(), MAPSIZE_X, MAPSIZE_Y, OVERMAP_DEPTH, and OVERMAP_HEIGHT.

Referenced by vehicle::act_on_map(), activity_on_turn_move_loot(), add_field(), add_item(), MapgenRemovePartHandler::add_item_or_charges(), add_item_or_charges(), add_vehicle(), add_vehicle_to_cache(), adjust_radiation(), ambient_light_at(), grid_furn_transform_queue::apply(), apply_light_source(), apply_vision_transparency_cache(), bash(), bash_rating(), build_sunlight_cache(), Character::check_outbounds_activity(), clear_path(), clear_vehicle_cache(), clear_vehicle_point_from_cache(), computer_at(), vehicle::damage_direct(), delete_graffiti(), delete_signage(), displace_vehicle(), explosion_handler::do_blast(), do_vehicle_caching(), draw(), game::draw_look_around_cursor(), drawsq(), ranged::execute_shaped_attack(), field_at(), furn(), furn_set(), generate_lightmap(), generic_multi_activity_handler(), get_field(), get_known_connections(), get_radiation(), get_signage(), get_submap_at(), get_temperature(), graffiti_at(), has_flag_ter_or_furn(), has_floor(), has_graffiti_at(), has_items(), i_at(), inbounds(), is_bashable(), is_outside(), light_at(), game::load_npcs(), maptile_at(), map_stack::max_volume(), move_cost(), move_cost_ter_furn(), obscured_by_vehicle_rotation(), obstructed_by_vehicle_rotation(), activity_handlers::operation_do_turn(), partial_con_at(), partial_con_remove(), partial_con_set(), pl_line_of_sight(), pl_sees(), game::print_all_tile_info(), remove_field(), remove_trap(), restore_vision_transparency_cache(), route(), npc::saw_player_recently(), sees(), set_graffiti(), set_radiation(), set_seen_cache_dirty(), set_signage(), set_temperature(), set_transparency_cache_dirty(), game::shift_monsters(), shift_traps(), shoot(), spawn_items(), ter(), ter_set(), tr_at(), trap_set(), update_suspension_cache(), valid_move(), and veh_at().

◆ inbounds() [2/2]

bool map::inbounds ( point  p) const
inline

Definition at line 1607 of file map.h.

1607 {
1608 return inbounds( tripoint( p, 0 ) );
1609 }

References inbounds().

◆ inbounds_z()

◆ invalidate_map_cache()

◆ invalidate_max_populated_zlev()

void map::invalidate_max_populated_zlev ( int  zlev)
private

Conditionally invalidates max_pupulated_zlev cache if the submap uniformity change occurs above current max_pupulated_zlev value.

Parameters
zlevzlevel where uniformity change occured

Definition at line 9093 of file map.cpp.

9094{
9095 if( max_populated_zlev && max_populated_zlev->second < zlev ) {
9096 max_populated_zlev->second = zlev;
9097 }
9098}

References max_populated_zlev.

Referenced by add_field(), add_item(), add_vehicle(), displace_vehicle(), furn_set(), shift_vehicle_z(), and ter_set().

◆ is_bashable() [1/2]

bool map::is_bashable ( const tripoint p,
bool  allow_floor = false 
) const

Returns true if there is a bashable vehicle part or the furn/terrain is bashable at p.

Definition at line 2483 of file map.cpp.

2484{
2485 if( !inbounds( p ) ) {
2486 dbg( DL::Warn ) << "Looking for out-of-bounds is_bashable at " << p;
2487 return false;
2488 }
2489
2490 if( veh_at( p ).obstacle_at_part() ) {
2491 return true;
2492 }
2493
2494 if( has_furn( p ) && furn( p ).obj().bash.str_max != -1 ) {
2495 return true;
2496 }
2497
2498 const auto &ter_bash = ter( p ).obj().bash;
2499 return ter_bash.str_max != -1 && ( !ter_bash.bash_below || allow_floor );
2500}

References bash(), map_data_common_t::bash, dbg, furn(), has_furn(), inbounds(), int_id< T >::obj(), map_bash_info::str_max, ter(), veh_at(), and Warn.

Referenced by MapExtras::burned_ground_parser(), activity_handlers::burrow_finish(), features(), game::fling_creature(), is_bashable(), npc::move_to(), MapExtras::mx_helicopter(), and activity_handlers::pickaxe_finish().

◆ is_bashable() [2/2]

bool map::is_bashable ( point  p) const
inline

Definition at line 960 of file map.h.

960 {
961 return is_bashable( tripoint( p, abs_sub.z ) );
962 }

References abs_sub, is_bashable(), and tripoint::z.

◆ is_bashable_furn() [1/2]

bool map::is_bashable_furn ( const tripoint p) const

Returns true if the furniture at p is bashable.

Definition at line 2508 of file map.cpp.

2509{
2510 return has_furn( p ) && furn( p ).obj().bash.str_max != -1;
2511}

References map_data_common_t::bash, furn(), has_furn(), int_id< T >::obj(), and map_bash_info::str_max.

Referenced by is_bashable_furn(), is_bashable_ter_furn(), and make_rubble().

◆ is_bashable_furn() [2/2]

bool map::is_bashable_furn ( point  p) const
inline

Definition at line 970 of file map.h.

970 {
971 return is_bashable_furn( tripoint( p, abs_sub.z ) );
972 }
bool is_bashable_furn(const tripoint &p) const
Returns true if the furniture at p is bashable.
Definition: map.cpp:2508

References abs_sub, is_bashable_furn(), and tripoint::z.

◆ is_bashable_ter() [1/2]

bool map::is_bashable_ter ( const tripoint p,
bool  allow_floor = false 
) const

Returns true if the terrain at p is bashable.

Definition at line 2502 of file map.cpp.

2503{
2504 const auto &ter_bash = ter( p ).obj().bash;
2505 return ter_bash.str_max != -1 && ( !ter_bash.bash_below || allow_floor );
2506}

References map_data_common_t::bash, int_id< T >::obj(), map_bash_info::str_max, and ter().

Referenced by is_bashable_ter(), is_bashable_ter_furn(), and make_rubble().

◆ is_bashable_ter() [2/2]

bool map::is_bashable_ter ( point  p) const
inline

Definition at line 965 of file map.h.

965 {
966 return is_bashable_ter( tripoint( p, abs_sub.z ) );
967 }
bool is_bashable_ter(const tripoint &p, bool allow_floor=false) const
Returns true if the terrain at p is bashable.
Definition: map.cpp:2502

References abs_sub, is_bashable_ter(), and tripoint::z.

◆ is_bashable_ter_furn() [1/2]

bool map::is_bashable_ter_furn ( const tripoint p,
bool  allow_floor = false 
) const

Returns true if the furniture or terrain at p is bashable.

Definition at line 2513 of file map.cpp.

2514{
2515 return is_bashable_furn( p ) || is_bashable_ter( p, allow_floor );
2516}

References is_bashable_furn(), and is_bashable_ter().

Referenced by is_bashable_ter_furn(), and vehicle::part_collision().

◆ is_bashable_ter_furn() [2/2]

bool map::is_bashable_ter_furn ( point  p) const
inline

Definition at line 975 of file map.h.

975 {
976 return is_bashable_ter_furn( tripoint( p, abs_sub.z ) );
977 }
bool is_bashable_ter_furn(const tripoint &p, bool allow_floor=false) const
Returns true if the furniture or terrain at p is bashable.
Definition: map.cpp:2513

References abs_sub, is_bashable_ter_furn(), and tripoint::z.

◆ is_cornerfloor()

bool map::is_cornerfloor ( const tripoint p) const

Definition at line 9030 of file map.cpp.

9031{
9032 if( impassable( p ) ) {
9033 return false;
9034 }
9035 std::set<tripoint> impassable_adjacent;
9036 for( const tripoint &pt : points_in_radius( p, 1 ) ) {
9037 if( impassable( pt ) ) {
9038 impassable_adjacent.insert( pt );
9039 }
9040 }
9041 if( !impassable_adjacent.empty() ) {
9042 //to check if a floor is a corner we first search if any of its diagonal adjacent points is impassable
9043 std::set< tripoint> diagonals = { p + tripoint_north_east, p + tripoint_north_west, p + tripoint_south_east, p + tripoint_south_west };
9044 for( const tripoint &impassable_diagonal : diagonals ) {
9045 if( impassable_adjacent.count( impassable_diagonal ) != 0 ) {
9046 //for every impassable diagonal found, we check if that diagonal terrain has at least two impassable neighbors that also neighbor point p
9047 int f = 0;
9048 for( const tripoint &l : points_in_radius( impassable_diagonal, 1 ) ) {
9049 if( impassable_adjacent.count( l ) != 0 ) {
9050 f++;
9051 }
9052 if( f > 2 ) {
9053 return true;
9054 }
9055 }
9056 }
9057 }
9058 }
9059 return false;
9060}
static constexpr tripoint tripoint_north_east
Definition: point.h:272
static constexpr tripoint tripoint_north_west
Definition: point.h:278
static constexpr tripoint tripoint_south_east
Definition: point.h:274
static constexpr tripoint tripoint_south_west
Definition: point.h:276

References impassable(), points_in_radius(), tripoint_north_east, tripoint_north_west, tripoint_south_east, and tripoint_south_west.

◆ is_divable() [1/2]

bool map::is_divable ( const tripoint p) const

Returns whether or not the terrain at the given location can be dived into (by monsters that can swim or are aquatic or non-breathing).

Parameters
pThe coordinate to look at.
Returns
true if the terrain can be dived into; false if not.

Definition at line 2627 of file map.cpp.

2628{
2629 return has_flag( "SWIMMABLE", p ) && has_flag( TFLAG_DEEP_WATER, p );
2630}

References has_flag(), and TFLAG_DEEP_WATER.

Referenced by enchantment::is_active(), is_divable(), and Creature::sees().

◆ is_divable() [2/2]

bool map::is_divable ( point  p) const
inline

Definition at line 1018 of file map.h.

1018 {
1019 return is_divable( tripoint( p, abs_sub.z ) );
1020 }
bool is_divable(const tripoint &p) const
Returns whether or not the terrain at the given location can be dived into (by monsters that can swim...
Definition: map.cpp:2627

References abs_sub, is_divable(), and tripoint::z.

◆ is_flammable()

bool map::is_flammable ( const tripoint p)

Returns true if there is a flammable item or field or the furn/terrain is flammable at p.

Definition at line 2711 of file map.cpp.

2712{
2713 if( flammable_items_at( p ) ) {
2714 return true;
2715 }
2716
2717 if( has_flag( "FLAMMABLE", p ) ) {
2718 return true;
2719 }
2720
2721 if( has_flag( "FLAMMABLE_ASH", p ) ) {
2722 return true;
2723 }
2724
2725 if( get_field_intensity( p, fd_web ) > 0 ) {
2726 return true;
2727 }
2728
2729 return false;
2730}
int get_field_intensity(const tripoint &p, const field_type_id &type) const
Get the intensity of a field entry (field_entry::intensity), if there is no field of that type,...
Definition: map.cpp:5440
bool flammable_items_at(const tripoint &p, int threshold=0)
Checks if there are any flammable items on the tile.
Definition: map.cpp:2694

References fd_web, flammable_items_at(), get_field_intensity(), and has_flag().

Referenced by Character::activate_bionic(), and activity_handlers::start_fire_do_turn().

◆ is_harvestable()

bool map::is_harvestable ( const tripoint pos) const

Returns true if point at pos is harvestable right now, with no extra tools.

Definition at line 1688 of file map.cpp.

1689{
1690 const auto &harvest_here = get_harvest( pos );
1691 return !harvest_here.is_null() && !harvest_here->empty();
1692}
const harvest_id & get_harvest(const tripoint &p) const
Returns the full harvest list, for spawning.
Definition: map.cpp:1622

References get_harvest(), and wrapped_vehicle::pos.

Referenced by npc::pick_up_item().

◆ is_last_ter_wall()

bool map::is_last_ter_wall ( bool  no_furn,
point  p,
point  max,
direction  dir 
) const

Check if the last terrain is wall in direction NORTH, SOUTH, WEST or EAST.

Parameters
no_furnif true, the function will stop and return false if it encounters a furniture
pstarting coordinates of check
maxending coordinates of check
dirDirection of check
Returns
true if from x to xmax or y to ymax depending on direction all terrain is floor and the last terrain is a wall

Definition at line 2642 of file map.cpp.

2644{
2645 point mov;
2646 switch( dir ) {
2647 case direction::NORTH:
2648 mov.y = -1;
2649 break;
2650 case direction::SOUTH:
2651 mov.y = 1;
2652 break;
2653 case direction::WEST:
2654 mov.x = -1;
2655 break;
2656 case direction::EAST:
2657 mov.x = 1;
2658 break;
2659 default:
2660 break;
2661 }
2662 point p2( p );
2663 bool result = true;
2664 bool loop = true;
2665 while( ( loop ) && ( ( dir == direction::NORTH && p2.y >= 0 ) ||
2666 ( dir == direction::SOUTH && p2.y < max.y ) ||
2667 ( dir == direction::WEST && p2.x >= 0 ) ||
2668 ( dir == direction::EAST && p2.x < max.x ) ) ) {
2669 if( no_furn && has_furn( p2 ) ) {
2670 loop = false;
2671 result = false;
2672 } else if( !has_flag_ter( "FLAT", p2 ) ) {
2673 loop = false;
2674 if( !has_flag_ter( "WALL", p2 ) ) {
2675 result = false;
2676 }
2677 }
2678 p2.x += mov.x;
2679 p2.y += mov.y;
2680 }
2681 return result;
2682}

References EAST, has_flag_ter(), has_furn(), NORTH, SOUTH, WEST, point::x, and point::y.

Referenced by find_potential_computer_point().

◆ is_outside() [1/2]

◆ is_outside() [2/2]

bool map::is_outside ( point  p) const
inline

Definition at line 1008 of file map.h.

1008 {
1009 return is_outside( tripoint( p, abs_sub.z ) );
1010 }
bool is_outside(const tripoint &p) const
Definition: map.cpp:2632

References abs_sub, is_outside(), and tripoint::z.

◆ is_suspension_valid()

bool map::is_suspension_valid ( const tripoint point)

Checks the four orientations in which a suspended tile could be valid, and returns if the tile is valid.

Definition at line 3031 of file map.cpp.

3032{
3033 if( ter( point + tripoint_east ) != t_open_air
3034 && ter( point + tripoint_west ) != t_open_air ) {
3035 return true;
3036 }
3039 return true;
3040 }
3042 && ter( point + tripoint_north ) != t_open_air ) {
3043 return true;
3044 }
3047 return true;
3048 }
3049 return false;
3050}
static constexpr tripoint tripoint_north
Definition: point.h:271
static constexpr tripoint tripoint_west
Definition: point.h:277
static constexpr tripoint tripoint_east
Definition: point.h:273
static constexpr tripoint tripoint_south
Definition: point.h:275

References t_open_air, ter(), tripoint_east, tripoint_north, tripoint_north_east, tripoint_north_west, tripoint_south, tripoint_south_east, tripoint_south_west, and tripoint_west.

Referenced by collapse_invalid_suspension(), and update_suspension_cache().

◆ is_transparent()

bool map::is_transparent ( const tripoint p) const

Returns whether the tile at p is transparent(you can look past it).

Definition at line 655 of file lightmap.cpp.

656{
658}

References light_transparency(), and LIGHT_TRANSPARENCY_SOLID.

Referenced by ranged::execute_shaped_attack(), ranged::expected_coverage(), get_known_connections(), mattack::riotbot(), and shoot().

◆ is_wall_adjacent()

bool map::is_wall_adjacent ( const tripoint center) const

Definition at line 1826 of file map.cpp.

1827{
1828 for( const tripoint &p : points_in_radius( center, 1 ) ) {
1829 if( p != center && impassable( p ) ) {
1830 return true;
1831 }
1832 }
1833 return false;
1834}

References center, impassable(), and points_in_radius().

Referenced by ma_requirements::is_valid_character().

◆ is_water_shallow_current() [1/2]

bool map::is_water_shallow_current ( const tripoint p) const

Definition at line 2622 of file map.cpp.

2623{
2624 return has_flag( "CURRENT", p ) && !has_flag( TFLAG_DEEP_WATER, p );
2625}

References has_flag(), and TFLAG_DEEP_WATER.

Referenced by is_water_shallow_current(), and iexamine::quern_examine().

◆ is_water_shallow_current() [2/2]

bool map::is_water_shallow_current ( point  p) const
inline

Definition at line 1022 of file map.h.

1022 {
1024 }
bool is_water_shallow_current(const tripoint &p) const
Definition: map.cpp:2622

References abs_sub, is_water_shallow_current(), and tripoint::z.

◆ light_at()

lit_level map::light_at ( const tripoint p) const

Definition at line 621 of file lightmap.cpp.

622{
623 if( !inbounds( p ) ) {
624 return lit_level::DARK; // Out of bounds
625 }
626
627 const auto &map_cache = get_cache_ref( p.z );
628 const auto &lm = map_cache.lm;
629 const auto &sm = map_cache.sm;
630 if( sm[p.x][p.y] >= LIGHT_SOURCE_BRIGHT ) {
631 return lit_level::BRIGHT;
632 }
633
634 const float max_light = lm[p.x][p.y].max();
635 if( max_light >= LIGHT_AMBIENT_LIT ) {
636 return lit_level::LIT;
637 }
638
639 if( max_light >= LIGHT_AMBIENT_LOW ) {
640 return lit_level::LOW;
641 }
642
643 return lit_level::DARK;
644}

References BRIGHT, DARK, get_cache_ref(), inbounds(), LIGHT_AMBIENT_LIT, LIGHT_AMBIENT_LOW, LIGHT_SOURCE_BRIGHT, LIT, LOW, coords::sm, tripoint::x, tripoint::y, and tripoint::z.

Referenced by Creature::sees().

◆ light_transparency()

float map::light_transparency ( const tripoint p) const

Definition at line 660 of file lightmap.cpp.

661{
662 return get_cache_ref( p.z ).transparency_cache[p.x][p.y];
663}

References get_cache_ref(), level_cache::transparency_cache, tripoint::x, tripoint::y, and tripoint::z.

Referenced by generate_lightmap(), and is_transparent().

◆ load() [1/2]

void map::load ( const tripoint w,
bool  update_vehicles,
bool  pump_events = false 
)

Load submaps into grid.

This might create new submaps if the mapbuffer can not deliver the requested submap (as it does not exist on disc). This must be called before the map can be used at all!

Parameters
wglobal coordinates of the submap at grid[0]. This is in submap coordinates.
update_vehiclesIf true, add vehicles to the vehicle cache.
pump_eventsIf true, handle window events during loading. If you set this to true, do ensure that the map is not accessed before this function returns (for example, UIs that draw the map should be disabled).

Definition at line 6683 of file map.cpp.

6684{
6685 for( auto &traps : traplocs ) {
6686 traps.clear();
6687 }
6688 field_furn_locs.clear();
6690 set_abs_sub( w );
6691 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
6692 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6693 loadn( point( gridx, gridy ), update_vehicle );
6694 if( pump_events ) {
6696 }
6697 }
6698 }
6700}
void pump_events()
Resize & refresh if necessary, process all pending window events, and ignore keypresses.
void loadn(const tripoint &grid, bool update_vehicles)
Definition: map.cpp:7065
input_manager inp_mngr
Definition: input.cpp:109

References field_furn_locs, inp_mngr, loadn(), my_MAPSIZE, input_manager::pump_events(), reset_vehicle_cache(), set_abs_sub(), submaps_with_active_items, and traplocs.

Referenced by start_location::add_map_extra(), add_monsters(), start_location::burn(), talk_function::buy_100_logs(), talk_function::buy_10_logs(), create_lab_consoles(), debug_menu::debug(), construct::done_digormine_stair(), construct::done_mine_upstair(), farm_action(), talk_function::field_build_1(), talk_function::field_build_2(), talk_function::field_harvest(), talk_function::field_plant(), find_valid_teleporters_omt(), basecamp::form_crafting_inventory(), mission_start::kill_horde_master(), load(), game::load_map(), talk_function::loot_building(), editmap::mapgen_veh_destroy(), editmap::mapgen_veh_query(), MapExtras::mx_minefield(), om_cutdown_trees(), om_harvest_furn(), om_harvest_itm(), om_harvest_ter(), om_set_hide_site(), teleporter_list::place_avatar_overmap(), Character::place_corpse(), mission_start::place_deposit_box(), mission_start::place_dog(), mission_start::place_npc_software(), mission_start::place_priest_diary(), basecamp::place_results(), game::place_vehicle_nearby(), mission_start::place_zombie_mom(), start_location::prepare_map(), mission_start::ranch_nurse_1(), mission_start::ranch_nurse_2(), mission_start::ranch_nurse_3(), mission_start::ranch_nurse_4(), mission_start::ranch_nurse_5(), mission_start::ranch_nurse_6(), mission_start::ranch_nurse_7(), mission_start::ranch_nurse_8(), mission_start::ranch_nurse_9(), mission_start::ranch_scavenger_1(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), mission_start::reveal_lab_train_depot(), debug_menu::spawn_nested_mapgen(), basecamp::start_relay_hide_site(), update_mapgen_function_json::update_map(), game::vertical_move(), and game::vertical_shift().

◆ load() [2/2]

void map::load ( const tripoint_abs_sm w,
bool  update_vehicles,
bool  pump_events = false 
)

Definition at line 6702 of file map.cpp.

6703{
6704 // TODO: fix point types
6705 load( w.raw(), update_vehicle, pump_events );
6706}
constexpr Point & raw()
Definition: coordinates.h:111
void load(const tripoint &w, bool update_vehicles, bool pump_events=false)
Load submaps into grid.
Definition: map.cpp:6683

References load(), and coords::coord_point< Point, Origin, Scale >::raw().

◆ loadn() [1/2]

void map::loadn ( const tripoint grid,
bool  update_vehicles 
)
protected

Definition at line 7065 of file map.cpp.

7066{
7067 // Cache empty overmap types
7068 static const oter_id rock( "empty_rock" );
7069 static const oter_id air( "open_air" );
7070
7071 const tripoint grid_abs_sub = abs_sub.xy() + grid;
7072 const size_t gridn = get_nonant( grid );
7073
7074 const int old_abs_z = abs_sub.z; // Ugly, but necessary at the moment
7075 abs_sub.z = grid.z;
7076
7077 submap *tmpsub = MAPBUFFER.lookup_submap( grid_abs_sub );
7078 if( tmpsub == nullptr ) {
7079 // It doesn't exist; we must generate it!
7080 dbg( DL::Info ) << "map::loadn: Missing mapbuffer data. Regenerating.";
7081
7082 // Each overmap square is two nonants; to prevent overlap, generate only at
7083 // squares divisible by 2.
7084 // TODO: fix point types
7085 const tripoint_abs_omt grid_abs_omt( sm_to_omt_copy( grid_abs_sub ) );
7086 const tripoint grid_abs_sub_rounded = omt_to_sm_copy( grid_abs_omt.raw() );
7087
7088 const oter_id terrain_type = overmap_buffer.ter( grid_abs_omt );
7089
7090 // Short-circuit if the map tile is uniform
7091 // TODO: Replace with json mapgen functions.
7092 if( terrain_type == air ) {
7093 generate_uniform( grid_abs_sub_rounded, t_open_air );
7094 } else if( terrain_type == rock ) {
7095 generate_uniform( grid_abs_sub_rounded, t_rock );
7096 } else {
7097 tinymap tmp_map;
7098 tmp_map.generate( grid_abs_sub_rounded, calendar::turn );
7099 }
7100
7101 // This is the same call to MAPBUFFER as above!
7102 tmpsub = MAPBUFFER.lookup_submap( grid_abs_sub );
7103 if( tmpsub == nullptr ) {
7104 debugmsg( "failed to generate a submap at %s", grid_abs_sub.to_string() );
7105 return;
7106 }
7107 }
7108
7109 // New submap changes the content of the map and all caches must be recalculated
7116 setsubmap( gridn, tmpsub );
7117 if( !tmpsub->active_items.empty() ) {
7118 submaps_with_active_items.emplace( grid_abs_sub );
7119 }
7120 if( tmpsub->field_count > 0 ) {
7121 get_cache( grid.z ).field_cache.set( grid.x + grid.y * MAPSIZE );
7122 }
7123 // Destroy bugged no-part vehicles
7124 auto &veh_vec = tmpsub->vehicles;
7125 for( auto iter = veh_vec.begin(); iter != veh_vec.end(); ) {
7126 vehicle *veh = iter->get();
7127 if( veh->part_count() > 0 ) {
7128 // Always fix submap coordinates for easier Z-level-related operations
7129 veh->sm_pos = grid;
7130 veh->attach();
7131 iter++;
7132 } else {
7134 if( veh->tracking_on ) {
7136 }
7137 dirty_vehicle_list.erase( veh );
7138 iter = veh_vec.erase( iter );
7139 }
7140 }
7141
7142 // Update vehicle data
7143 if( update_vehicles ) {
7144 auto &map_cache = get_cache( grid.z );
7145 for( const auto &veh : tmpsub->vehicles ) {
7146 // Only add if not tracking already.
7147 if( map_cache.vehicle_list.find( veh.get() ) == map_cache.vehicle_list.end() ) {
7148 map_cache.vehicle_list.insert( veh.get() );
7149 if( !veh->loot_zones.empty() ) {
7150 map_cache.zone_vehicles.insert( veh.get() );
7151 }
7152 add_vehicle_to_cache( veh.get() );
7153 }
7154 }
7155 }
7156
7157 actualize( grid );
7158
7159 abs_sub.z = old_abs_z;
7160}
void set_suspension_cache_dirty(const int zlev)
Definition: map.cpp:227
void generate(const tripoint &p, const time_point &when)
Definition: mapgen.cpp:107
void actualize(const tripoint &grid)
Fast forward a submap that has just been loading into this map.
Definition: map.cpp:7480
submap * lookup_submap(const tripoint &p)
Get a submap stored in this buffer.
Definition: mapbuffer.cpp:88
Definition: map.h:2048
std::unordered_multimap< point, zone_data > loot_zones
Definition: vehicle.h:1888
int part_count() const
Definition: vehicle.cpp:7079
void attach()
Definition: vehicle.h:765
point omt_to_sm_copy(point p)
static void generate_uniform(const tripoint &p, const ter_id &terrain_type)
Definition: map.cpp:7049
mapbuffer MAPBUFFER
Definition: mapbuffer.cpp:40

References abs_sub, submap::active_items, actualize(), add_vehicle_to_cache(), vehicle::attach(), dbg, debugmsg, dirty_vehicle_list, active_item_cache::empty(), level_cache::field_cache, submap::field_count, generate(), generate_uniform(), get_cache(), get_nonant(), grid, Info, mapbuffer::lookup_submap(), MAPBUFFER, MAPSIZE, omt_to_sm_copy(), overmap_buffer, vehicle::part_count(), coords::coord_point< Point, Origin, Scale >::raw(), overmapbuffer::remove_vehicle(), reset_vehicle_cache(), set_floor_cache_dirty(), set_outside_cache_dirty(), set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_suspension_cache_dirty(), set_transparency_cache_dirty(), setsubmap(), vehicle::sm_pos, sm_to_omt_copy(), submaps_with_active_items, t_open_air, t_rock, overmapbuffer::ter(), tripoint::to_string(), vehicle::tracking_on, calendar::turn, submap::vehicles, tripoint::xy(), and tripoint::z.

Referenced by load(), loadn(), and shift().

◆ loadn() [2/2]

void map::loadn ( point  grid,
bool  update_vehicles 
)
inlineprotected

Definition at line 1661 of file map.h.

1661 {
1662 if( zlevels ) {
1663 for( int gridz = -OVERMAP_DEPTH; gridz <= OVERMAP_HEIGHT; gridz++ ) {
1664 loadn( tripoint( grid, gridz ), update_vehicles );
1665 }
1666
1667 // Note: we want it in a separate loop! It is a post-load cleanup
1668 // Since we're adding roofs, we want it to go up (from lowest to highest)
1669 for( int gridz = -OVERMAP_DEPTH; gridz <= OVERMAP_HEIGHT; gridz++ ) {
1670 add_roofs( tripoint( grid, gridz ) );
1671 }
1672 } else {
1673 loadn( tripoint( grid, abs_sub.z ), update_vehicles );
1674 }
1675 }
void add_roofs(const tripoint &grid)
Hacks in missing roofs.
Definition: map.cpp:7535

References abs_sub, add_roofs(), grid, loadn(), OVERMAP_DEPTH, OVERMAP_HEIGHT, tripoint::z, and zlevels.

◆ make_active()

void map::make_active ( item_location loc)

Update an item's active status, for example when adding hot or perishable liquid to a container.

Definition at line 4486 of file map.cpp.

4487{
4488 item *target = loc.get_item();
4489
4490 // Trust but verify, don't let stinking callers set items active when they shouldn't be.
4491 if( !target->needs_processing() ) {
4492 return;
4493 }
4494 point l;
4495 submap *const current_submap = get_submap_at( loc.position(), l );
4496 cata::colony<item> &item_stack = current_submap->get_items( l );
4498
4499 if( current_submap->active_items.empty() ) {
4501 abs_sub.y + loc.position().y / SEEY, loc.position().z ) );
4502 }
4503 current_submap->active_items.add( *iter, l );
4504}
item * get_item()
Gets the selected item or nullptr.
tripoint position() const
Returns the position where the item is found.

References abs_sub, submap::active_items, active_item_cache::add(), active_item_cache::empty(), item_location::get_item(), submap::get_items(), item_stack::get_iterator_from_pointer(), get_submap_at(), item::needs_processing(), item_location::position(), SEEX, SEEY, submaps_with_active_items, tripoint::x, tripoint::y, and tripoint::z.

Referenced by make_active(), and liquid_handler::perform_liquid_transfer().

◆ make_rubble() [1/3]

void map::make_rubble ( const tripoint p)
inline

Definition at line 1003 of file map.h.

1003 {
1004 make_rubble( p, f_rubble, false, t_dirt, false );
1005 }

References f_rubble, make_rubble(), and t_dirt.

◆ make_rubble() [2/3]

void map::make_rubble ( const tripoint p,
const furn_id rubble_type,
bool  items 
)
inline

Definition at line 1000 of file map.h.

1000 {
1001 make_rubble( p, rubble_type, items, t_dirt, false );
1002 }

References make_rubble(), and t_dirt.

◆ make_rubble() [3/3]

void map::make_rubble ( const tripoint p,
const furn_id rubble_type,
bool  items,
const ter_id floor_type,
bool  overwrite = false 
)

Generates rubble at the given location, if overwrite is true it just writes on top of what currently exists floor_type is only used if there is a non-bashable wall at the location or with overwrite = true.

Definition at line 2567 of file map.cpp.

2569{
2570 if( overwrite ) {
2571 ter_set( p, floor_type );
2572 furn_set( p, rubble_type );
2573 } else {
2574 // First see if there is existing furniture to destroy
2575 if( is_bashable_furn( p ) ) {
2576 destroy_furn( p, true );
2577 }
2578 // Leave the terrain alone unless it interferes with furniture placement
2579 if( impassable( p ) && is_bashable_ter( p ) ) {
2580 destroy( p, true );
2581 }
2582 // Check again for new terrain after potential destruction
2583 if( impassable( p ) ) {
2584 ter_set( p, floor_type );
2585 }
2586
2587 furn_set( p, rubble_type );
2588 }
2589
2590 if( !items ) {
2591 return;
2592 }
2593
2594 //Still hardcoded, but a step up from the old stuff due to being in only one place
2595 if( rubble_type == f_wreckage ) {
2596 item chunk( "steel_chunk", calendar::turn );
2597 item scrap( "scrap", calendar::turn );
2598 add_item_or_charges( p, chunk );
2599 add_item_or_charges( p, scrap );
2600 if( one_in( 5 ) ) {
2601 item pipe( "pipe", calendar::turn );
2602 item wire( "wire", calendar::turn );
2603 add_item_or_charges( p, pipe );
2604 add_item_or_charges( p, wire );
2605 }
2606 } else if( rubble_type == f_rubble_rock ) {
2607 item rock( "rock", calendar::turn );
2608 int rock_count = rng( 1, 3 );
2609 for( int i = 0; i < rock_count; i++ ) {
2610 add_item_or_charges( p, rock );
2611 }
2612 } else if( rubble_type == f_rubble ) {
2613 item splinter( "splinter", calendar::turn );
2614 int splinter_count = rng( 2, 8 );
2615 for( int i = 0; i < splinter_count; i++ ) {
2616 add_item_or_charges( p, splinter );
2617 }
2618 spawn_item( p, itype_nail, 1, rng( 20, 50 ) );
2619 }
2620}
void destroy_furn(const tripoint &p, bool silent=false)
Keeps bashing a square until there is no more furniture.
Definition: map.cpp:3712
static const itype_id itype_nail("nail")

References add_item_or_charges(), destroy(), destroy_furn(), f_rubble, f_rubble_rock, f_wreckage, furn_set(), impassable(), is_bashable_furn(), is_bashable_ter(), itype_nail, one_in(), rng(), spawn_item(), ter_set(), and calendar::turn.

Referenced by computer_session::action_irradiator(), computer_session::action_srcf_seal(), jmapgen_make_rubble::apply(), collapse_at(), draw_lab(), draw_mine(), computer_session::failure_pump_explode(), make_rubble(), mapgen_crater(), MapExtras::mx_helicopter(), and MapExtras::mx_portal().

◆ maptile_at() [1/2]

maptile map::maptile_at ( const tripoint p)

Definition at line 268 of file map.cpp.

269{
270 if( !inbounds( p ) ) {
271 return maptile( &null_submap, point_zero );
272 }
273
274 return maptile_at_internal( p );
275}
static submap null_submap
Definition: map.cpp:257

References inbounds(), maptile_at_internal(), null_submap, and point_zero.

◆ maptile_at() [2/2]

◆ maptile_at_internal() [1/2]

maptile map::maptile_at_internal ( const tripoint p)
private

Definition at line 285 of file map.cpp.

286{
287 point l;
288 submap *const sm = get_submap_at( p, l );
289
290 return maptile( sm, l );
291}

References get_submap_at(), and coords::sm.

◆ maptile_at_internal() [2/2]

maptile map::maptile_at_internal ( const tripoint p) const
private

Definition at line 277 of file map.cpp.

278{
279 point l;
280 submap *const sm = get_submap_at( p, l );
281
282 return maptile( sm, l );
283}

References get_submap_at(), and coords::sm.

Referenced by draw(), maptile_at(), maptile_has_bounds(), process_fields_in_submap(), route(), and spread_gas().

◆ maptile_has_bounds()

std::pair< tripoint, maptile > map::maptile_has_bounds ( const tripoint p,
bool  bounds_checked 
)
private

Definition at line 180 of file map_field.cpp.

181{
182 if( bounds_checked ) {
183 // We know that the point is in bounds
184 return {p, maptile_at_internal( p )};
185 }
186
187 return {p, maptile_at( p )};
188}

References maptile_at(), and maptile_at_internal().

Referenced by get_neighbors().

◆ max_volume()

units::volume map::max_volume ( const tripoint p)

Definition at line 4277 of file map.cpp.

4278{
4279 return i_at( p ).max_volume();
4280}
units::volume max_volume() const override
Maximum volume allowed here.
Definition: map.cpp:162

References i_at(), and map_stack::max_volume().

Referenced by advanced_inventory::print_items().

◆ mod_field_age()

time_duration map::mod_field_age ( const tripoint p,
const field_type_id type,
const time_duration offset 
)

Increment/decrement age of field entry at point.

Returns
resulting age or -1_turns if not present (does not create a new field).

Definition at line 5389 of file map.cpp.

5391{
5392 return set_field_age( p, type, offset, true );
5393}
time_duration set_field_age(const tripoint &p, const field_type_id &type, const time_duration &age, bool isoffset=false)
Set age of field entry at point.
Definition: map.cpp:5400

References set_field_age(), and type.

Referenced by game::process_artifact().

◆ mod_field_intensity()

int map::mod_field_intensity ( const tripoint p,
const field_type_id type,
int  offset 
)

Increment/decrement intensity of field entry at point, creating if not present, removing if intensity becomes 0.

Returns
resulting intensity, or 0 for not present (either removed or not created at all).

Definition at line 5395 of file map.cpp.

5396{
5397 return set_field_intensity( p, type, offset, true );
5398}
int set_field_intensity(const tripoint &p, const field_type_id &type, int new_intensity, bool isoffset=false)
Set intensity of field entry at point, creating if not present, removing if intensity becomes 0.
Definition: map.cpp:5413

References set_field_intensity(), and type.

Referenced by add_splatter(), and propagate_field().

◆ monster_in_field()

void map::monster_in_field ( monster z)
protected

Definition at line 1632 of file map_field.cpp.

1633{
1634 if( z.digging() ) {
1635 // Digging monsters are immune to fields
1636 return;
1637 }
1638 if( veh_at( z.pos() ) ) {
1639 // FIXME: Immune when in a vehicle for now.
1640 return;
1641 }
1642 field &curfield = get_field( z.pos() );
1643
1644 int dam = 0;
1645 // Iterate through all field effects on this tile.
1646 // Do not remove the field with remove_field, instead set it's intensity to 0. It will be removed
1647 // later by the field processing, which will also adjust field_count accordingly.
1648 for( auto &field_list_it : curfield ) {
1649 field_entry &cur = field_list_it.second;
1650 if( !cur.is_field_alive() ) {
1651 continue;
1652 }
1653 const field_type_id cur_field_type = cur.get_field_type();
1654 if( cur_field_type == fd_web ) {
1655 if( !z.has_flag( MF_WEBWALK ) ) {
1656 z.add_effect( effect_webbed, 1_turns, num_bp, cur.get_field_intensity() );
1657 cur.set_field_intensity( 0 );
1658 }
1659 }
1660 if( cur_field_type == fd_acid ) {
1661 if( !z.flies() ) {
1662 const int d = rng( cur.get_field_intensity(), cur.get_field_intensity() * 3 );
1663 z.deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_ACID, d ) );
1664 z.check_dead_state();
1665 if( d > 0 ) {
1666 z.add_effect( effect_corroding, 1_turns * rng( d / 2, d * 2 ) );
1667 }
1668 }
1669
1670 }
1671 if( cur_field_type == fd_sap ) {
1672 z.moves -= cur.get_field_intensity() * 5;
1674 }
1675 if( cur_field_type == fd_sludge ) {
1676 if( !z.digs() && !z.flies() &&
1677 !z.has_flag( MF_SLUDGEPROOF ) ) {
1678 z.moves -= cur.get_field_intensity() * 300;
1679 cur.set_field_intensity( 0 );
1680 }
1681 }
1682 if( cur_field_type == fd_fire ) {
1683 // TODO: MATERIALS Use fire resistance
1684 if( z.has_flag( MF_FIREPROOF ) || z.has_flag( MF_FIREY ) ) {
1685 return;
1686 }
1687 // TODO: Replace the section below with proper json values
1689 dam += 3;
1690 }
1691 if( z.made_of( material_id( "veggy" ) ) ) {
1692 dam += 12;
1693 }
1695 dam += 20;
1696 }
1698 dam += -20;
1699 }
1700 if( z.flies() ) {
1701 dam -= 15;
1702 }
1703 dam -= z.get_armor_type( DT_HEAT, bodypart_id( "torso" ) );
1704
1705 if( cur.get_field_intensity() == 1 ) {
1706 dam += rng( 2, 6 );
1707 } else if( cur.get_field_intensity() == 2 ) {
1708 dam += rng( 6, 12 );
1709 if( !z.flies() ) {
1710 z.moves -= 20;
1711 if( dam > 0 ) {
1712 z.add_effect( effect_onfire, 1_turns * rng( dam / 2, dam * 2 ) );
1713 }
1714 }
1715 } else if( cur.get_field_intensity() == 3 ) {
1716 dam += rng( 10, 20 );
1717 if( !z.flies() || one_in( 3 ) ) {
1718 z.moves -= 40;
1719 if( dam > 0 ) {
1720 z.add_effect( effect_onfire, 1_turns * rng( dam / 2, dam * 2 ) );
1721 }
1722 }
1723 }
1724 }
1725 if( cur_field_type == fd_smoke ) {
1726 if( !z.has_flag( MF_NO_BREATHE ) ) {
1727 if( cur.get_field_intensity() == 3 ) {
1728 z.moves -= rng( 10, 20 );
1729 }
1730 // Plants suffer from smoke even worse
1731 if( z.made_of( material_id( "veggy" ) ) ) {
1732 z.moves -= rng( 1, cur.get_field_intensity() * 12 );
1733 }
1734 }
1735
1736 }
1737 if( cur_field_type == fd_tear_gas ) {
1739 if( cur.get_field_intensity() == 3 ) {
1740 z.add_effect( effect_stunned, rng( 1_minutes, 2_minutes ) );
1741 dam += rng( 4, 10 );
1742 } else if( cur.get_field_intensity() == 2 ) {
1743 z.add_effect( effect_stunned, rng( 5_turns, 10_turns ) );
1744 dam += rng( 2, 5 );
1745 } else {
1746 z.add_effect( effect_stunned, rng( 1_turns, 5_turns ) );
1747 }
1748 if( z.made_of( material_id( "veggy" ) ) ) {
1749 z.moves -= rng( cur.get_field_intensity() * 5, cur.get_field_intensity() * 12 );
1750 dam += cur.get_field_intensity() * rng( 8, 14 );
1751 }
1752 if( z.has_flag( MF_SEES ) ) {
1753 z.add_effect( effect_blind, cur.get_field_intensity() * 8_turns );
1754 }
1755 }
1756
1757 }
1758 if( cur_field_type == fd_relax_gas ) {
1760 z.add_effect( effect_stunned, rng( cur.get_field_intensity() * 4_turns,
1761 cur.get_field_intensity() * 8_turns ) );
1762 }
1763 }
1764 if( cur_field_type == fd_dazzling ) {
1765 if( z.has_flag( MF_SEES ) && !z.has_flag( MF_ELECTRONIC ) ) {
1766 z.add_effect( effect_blind, cur.get_field_intensity() * 12_turns );
1767 z.add_effect( effect_stunned, cur.get_field_intensity() * rng( 5_turns, 12_turns ) );
1768 }
1769
1770 }
1771 if( cur_field_type == fd_toxic_gas ) {
1772 if( !z.has_flag( MF_NO_BREATHE ) ) {
1773 dam += cur.get_field_intensity();
1774 z.moves -= cur.get_field_intensity();
1775 }
1776
1777 }
1778 if( cur_field_type == fd_nuke_gas ) {
1779 if( !z.has_flag( MF_NO_BREATHE ) ) {
1780 if( cur.get_field_intensity() == 3 ) {
1781 z.moves -= rng( 60, 120 );
1782 dam += rng( 30, 50 );
1783 } else if( cur.get_field_intensity() == 2 ) {
1784 z.moves -= rng( 20, 50 );
1785 dam += rng( 10, 25 );
1786 } else {
1787 z.moves -= rng( 0, 15 );
1788 dam += rng( 0, 12 );
1789 }
1790 if( z.made_of( material_id( "veggy" ) ) ) {
1791 z.moves -= rng( cur.get_field_intensity() * 5, cur.get_field_intensity() * 12 );
1792 dam *= cur.get_field_intensity();
1793 }
1794 }
1795
1796 }
1797 if( cur_field_type == fd_flame_burst ) {
1798 // TODO: MATERIALS Use fire resistance
1799 if( z.has_flag( MF_FIREPROOF ) || z.has_flag( MF_FIREY ) ) {
1800 return;
1801 }
1803 dam += 3;
1804 }
1805 if( z.made_of( material_id( "veggy" ) ) ) {
1806 dam += 12;
1807 }
1809 dam += 50;
1810 }
1812 dam += -25;
1813 }
1814 dam += rng( 0, 8 );
1815 z.moves -= 20;
1816 }
1817 if( cur_field_type == fd_electricity ) {
1818 // We don't want to increase dam, but deal a separate hit so that it can apply effects
1819 z.deal_damage( nullptr, bodypart_id( "torso" ),
1820 damage_instance( DT_ELECTRIC, rng( 1, cur.get_field_intensity() * 3 ) ) );
1821 }
1822 if( cur_field_type == fd_fatigue ) {
1823 if( rng( 0, 2 ) < cur.get_field_intensity() ) {
1824 dam += cur.get_field_intensity();
1825 teleport::teleport( z );
1826 }
1827 }
1828 if( cur_field_type == fd_incendiary ) {
1829 // TODO: MATERIALS Use fire resistance
1830 if( z.has_flag( MF_FIREPROOF ) || z.has_flag( MF_FIREY ) ) {
1831 return;
1832 }
1834 dam += 3;
1835 }
1836 if( z.made_of( material_id( "veggy" ) ) ) {
1837 dam += 12;
1838 }
1840 dam += 20;
1841 }
1843 dam += -5;
1844 }
1845
1846 if( cur.get_field_intensity() == 1 ) {
1847 dam += rng( 2, 6 );
1848 } else if( cur.get_field_intensity() == 2 ) {
1849 dam += rng( 6, 12 );
1850 z.moves -= 20;
1851 if( !z.made_of( LIQUID ) && !z.made_of_any( Creature::cmat_flameres ) ) {
1852 z.add_effect( effect_onfire, rng( 8_turns, 12_turns ) );
1853 }
1854 } else if( cur.get_field_intensity() == 3 ) {
1855 dam += rng( 10, 20 );
1856 z.moves -= 40;
1857 if( !z.made_of( LIQUID ) && !z.made_of_any( Creature::cmat_flameres ) ) {
1858 z.add_effect( effect_onfire, rng( 12_turns, 16_turns ) );
1859 }
1860 }
1861 }
1862 if( cur_field_type == fd_fungal_haze ) {
1863 if( !z.type->in_species( FUNGUS ) &&
1864 !z.type->has_flag( MF_NO_BREATHE ) &&
1865 !z.make_fungus() ) {
1866 // Don't insta-kill jabberwocks, that's silly
1867 const int intensity = cur.get_field_intensity();
1868 z.moves -= rng( 10 * intensity, 30 * intensity );
1869 dam += rng( 0, 10 * intensity );
1870 }
1871 }
1872 if( cur_field_type == fd_fungicidal_gas ) {
1873 if( z.type->in_species( FUNGUS ) ) {
1874 const int intensity = cur.get_field_intensity();
1875 z.moves -= rng( 10 * intensity, 30 * intensity );
1876 dam += rng( 4, 7 * intensity );
1877 }
1878 }
1879 if( cur_field_type == fd_insecticidal_gas ) {
1880 if( z.type->in_species( INSECT ) || z.type->in_species( SPIDER ) ) {
1881 const int intensity = cur.get_field_intensity();
1882 z.moves -= rng( 10 * intensity, 30 * intensity );
1883 dam += rng( 4, 7 * intensity );
1884 }
1885 }
1886 }
1887
1888 if( dam > 0 ) {
1889 z.apply_damage( nullptr, bodypart_id( "torso" ), dam, true );
1890 z.check_dead_state();
1891 }
1892}
static const std::set< material_id > cmat_flammable
Definition: creature.h:481
virtual dealt_damage_instance deal_damage(Creature *source, bodypart_id bp, const damage_instance &dam)
Deals the damage via an attack.
Definition: creature.cpp:880
static const std::set< material_id > cmat_flesh
Definition: creature.h:479
int moves
Definition: creature.h:574
static const std::set< material_id > cmat_fleshnveg
Definition: creature.h:480
static const std::set< material_id > cmat_flameres
Definition: creature.h:482
bool has_flag(m_flag f) const override
Definition: monster.cpp:898
bool digs() const
Definition: monster.cpp:940
bool made_of_any(const std::set< material_id > &ms) const override
Definition: monster.cpp:992
void add_effect(const efftype_id &eff_id, const time_duration &dur, const bodypart_str_id &bp, int intensity=0, bool force=false, bool deferred=false) override
Performs any monster-specific modifications to the arguments before passing to Creature::add_effect()...
Definition: monster.cpp:1840
bool make_fungus()
Makes this monster into a fungus version Returns false if no such monster exists Returns true if mons...
Definition: monster.cpp:2632
const tripoint & pos() const override
Definition: monster.cpp:256
bool made_of(const material_id &m) const override
Definition: monster.cpp:987
const mtype * type
Definition: monster.h:477
int get_armor_type(damage_type dt, bodypart_id bp) const override
Definition: monster.cpp:1901
bool flies() const
Definition: monster.cpp:945
bool digging() const override
Definition: monster.cpp:930
@ DT_ELECTRIC
Definition: damage.h:30
@ DT_HEAT
Definition: damage.h:28
field_type_id fd_incendiary
Definition: field_type.cpp:372
field_type_id fd_toxic_gas
Definition: field_type.cpp:347
field_type_id fd_tear_gas
Definition: field_type.cpp:348
field_type_id fd_sludge
Definition: field_type.cpp:344
field_type_id fd_nuke_gas
Definition: field_type.cpp:349
field_type_id fd_dazzling
Definition: field_type.cpp:361
field_type_id fd_electricity
Definition: field_type.cpp:353
field_type_id fd_fungal_haze
Definition: field_type.cpp:374
field_type_id fd_smoke
Definition: field_type.cpp:346
field_type_id fd_sap
Definition: field_type.cpp:343
field_type_id fd_fungicidal_gas
Definition: field_type.cpp:383
field_type_id fd_acid
Definition: field_type.cpp:342
field_type_id fd_flame_burst
Definition: field_type.cpp:352
field_type_id fd_relax_gas
Definition: field_type.cpp:373
field_type_id fd_fatigue
Definition: field_type.cpp:354
field_type_id fd_insecticidal_gas
Definition: field_type.cpp:384
static const efftype_id effect_blind("blind")
static const species_id FUNGUS("FUNGUS")
static const species_id INSECT("INSECT")
static const efftype_id effect_webbed("webbed")
static const efftype_id effect_stunned("stunned")
static const species_id SPIDER("SPIDER")
static const efftype_id effect_onfire("onfire")
@ MF_SEES
Definition: mtype.h:67
@ MF_FIREY
Definition: mtype.h:103
@ MF_WEBWALK
Definition: mtype.h:85
@ MF_FIREPROOF
Definition: mtype.h:99
@ MF_SLUDGEPROOF
Definition: mtype.h:100
@ MF_ELECTRONIC
Definition: mtype.h:105
@ MF_NO_BREATHE
Definition: mtype.h:123
bool teleport(Creature &critter, int min_distance=2, int max_distance=12, bool safe=false, bool add_teleglow=true)
Teleports a creature to a tile within min_distance and max_distance tiles.
Definition: teleport.cpp:24
bool has_flag(m_flag flag) const
Definition: mtype.cpp:75
bool in_species(const species_id &spec) const
Definition: mtype.cpp:122

References monster::add_effect(), monster::apply_damage(), Creature::check_dead_state(), Creature::cmat_flameres, Creature::cmat_flammable, Creature::cmat_flesh, Creature::cmat_fleshnveg, Creature::deal_damage(), monster::digging(), monster::digs(), DT_ACID, DT_ELECTRIC, DT_HEAT, effect_blind, effect_corroding, effect_onfire, effect_stunned, effect_webbed, fd_acid, fd_dazzling, fd_electricity, fd_fatigue, fd_fire, fd_flame_burst, fd_fungal_haze, fd_fungicidal_gas, fd_incendiary, fd_insecticidal_gas, fd_nuke_gas, fd_relax_gas, fd_sap, fd_sludge, fd_smoke, fd_tear_gas, fd_toxic_gas, fd_web, monster::flies(), FUNGUS, monster::get_armor_type(), get_field(), field_entry::get_field_intensity(), field_entry::get_field_type(), monster::has_flag(), mtype::has_flag(), mtype::in_species(), INSECT, field_entry::is_field_alive(), LIQUID, monster::made_of(), monster::made_of_any(), monster::make_fungus(), MF_ELECTRONIC, MF_FIREPROOF, MF_FIREY, MF_NO_BREATHE, MF_SEES, MF_SLUDGEPROOF, MF_WEBWALK, Creature::moves, num_bp, one_in(), monster::pos(), rng(), field_entry::set_field_intensity(), SPIDER, teleport::teleport(), monster::type, and veh_at().

Referenced by creature_in_field().

◆ mop_spills()

bool map::mop_spills ( const tripoint p)

Remove moppable fields/items at this location.

Parameters
pthe location
Returns
true if anything moppable was there, false otherwise.

Definition at line 2863 of file map.cpp.

2864{
2865 bool retval = false;
2866
2867 if( !has_flag( "LIQUIDCONT", p ) && !has_flag( "SEALED", p ) ) {
2868 auto items = i_at( p );
2869 auto new_end = std::remove_if( items.begin(), items.end(), []( const item & it ) {
2870 return it.made_of( LIQUID );
2871 } );
2872 retval = new_end != items.end();
2873 while( new_end != items.end() ) {
2874 new_end = items.erase( new_end );
2875 }
2876 }
2877
2878 field &fld = field_at( p );
2879 static const std::vector<field_type_id> to_check = {
2880 fd_blood,
2888 fd_bile,
2889 fd_slime,
2890 fd_sludge
2891 };
2892 for( field_type_id fid : to_check ) {
2893 retval |= fld.remove_field( fid );
2894 }
2895
2896 if( const optional_vpart_position vp = veh_at( p ) ) {
2897 vehicle *const veh = &vp->vehicle();
2898 std::vector<int> parts_here = veh->parts_at_relative( vp->mount(), true );
2899 for( auto &elem : parts_here ) {
2900 if( veh->part( elem ).blood > 0 ) {
2901 veh->part( elem ).blood = 0;
2902 retval = true;
2903 }
2904 //remove any liquids that somehow didn't fall through to the ground
2905 vehicle_stack here = veh->get_items( elem );
2906 auto new_end = std::remove_if( here.begin(), here.end(), []( const item & it ) {
2907 return it.made_of( LIQUID );
2908 } );
2909 retval |= ( new_end != here.end() );
2910 while( new_end != here.end() ) {
2911 new_end = here.erase( new_end );
2912 }
2913 }
2914 } // if veh != 0
2915 return retval;
2916}
bool remove_field(const field_type_id &field_to_remove)
Removes the field entry with a type equal to the field_type_id parameter.
Definition: field.cpp:219
iterator erase(const_iterator it) override
Definition: vehicle.cpp:231
std::vector< int > parts_at_relative(point dp, bool use_cache) const
Definition: vehicle.cpp:2417
field_type_id fd_gibs_insect
Definition: field_type.cpp:365
field_type_id fd_blood_insect
Definition: field_type.cpp:363
field_type_id fd_bile
Definition: field_type.cpp:337
field_type_id fd_blood_invertebrate
Definition: field_type.cpp:364
field_type_id fd_blood_veggy
Definition: field_type.cpp:362
field_type_id fd_gibs_veggy
Definition: field_type.cpp:339
field_type_id fd_blood
Definition: field_type.cpp:336
field_type_id fd_slime
Definition: field_type.cpp:341
field_type_id fd_gibs_invertebrate
Definition: field_type.cpp:366
field_type_id fd_gibs_flesh
Definition: field_type.cpp:338

References item_stack::begin(), vehicle_part::blood, item_stack::end(), vehicle_stack::erase(), fd_bile, fd_blood, fd_blood_insect, fd_blood_invertebrate, fd_blood_veggy, fd_gibs_flesh, fd_gibs_insect, fd_gibs_invertebrate, fd_gibs_veggy, fd_slime, fd_sludge, field_at(), vehicle::get_items(), has_flag(), i_at(), vehicle::part(), vehicle::parts_at_relative(), field::remove_field(), veh_at(), and vehicle::vehicle().

◆ move_cost() [1/2]

int map::move_cost ( const tripoint p,
const vehicle ignored_vehicle = nullptr 
) const

Calculate the cost to move past the tile at p.

The move cost is determined by various obstacles, such as terrain, vehicles and furniture.

Note
Movement costs for players and zombies both use this function.
Returns
The return value is interpreted as follows:
Move Cost Meaning
0 Impassable. Use passable/impassable to check for this.
n > 0 x*n turns to move past this

Definition at line 1838 of file map.cpp.

1839{
1840 if( !inbounds( p ) ) {
1841 return 0;
1842 }
1843
1844 const furn_t &furniture = furn( p ).obj();
1845 const ter_t &terrain = ter( p ).obj();
1846 const optional_vpart_position vp = veh_at( p );
1847 vehicle *const veh = ( !vp || &vp->vehicle() == ignored_vehicle ) ? nullptr : &vp->vehicle();
1848 const int part = veh ? vp->part_index() : -1;
1849
1850 return move_cost_internal( furniture, terrain, veh, part );
1851}
int move_cost_internal(const furn_t &furniture, const ter_t &terrain, const vehicle *veh, int vpart) const
Internal versions of public functions to avoid checking same variables multiple times.
Definition: map.cpp:1801

References furn(), furniture, inbounds(), move_cost_internal(), int_id< T >::obj(), ter(), terrain, and veh_at().

Referenced by character_funcs::base_comfort_value(), activity_handlers::burrow_finish(), combined_movecost(), draw_mine(), game::grabbed_veh_move(), place_trap_actor::is_allowed(), is_solid_neighbor(), mine_activity(), npc::move_away_from(), move_cost(), obstacle_coverage(), passable(), activity_handlers::pickaxe_finish(), game::print_terrain_info(), reachable_flood_steps(), deploy_furn_actor::use(), game::vertical_move(), and game::walk_move().

◆ move_cost() [2/2]

int map::move_cost ( point  p,
const vehicle ignored_vehicle = nullptr 
) const
inline

Definition at line 562 of file map.h.

562 {
563 return move_cost( tripoint( p, abs_sub.z ), ignored_vehicle );
564 }

References abs_sub, move_cost(), and tripoint::z.

◆ move_cost_internal()

int map::move_cost_internal ( const furn_t furniture,
const ter_t terrain,
const vehicle veh,
int  vpart 
) const
private

Internal versions of public functions to avoid checking same variables multiple times.

They lack safety checks, because their callers already do those.

Definition at line 1801 of file map.cpp.

1803{
1804 if( terrain.movecost == 0 || ( furniture.id && furniture.movecost < 0 ) ) {
1805 return 0;
1806 }
1807
1808 if( veh != nullptr ) {
1809 const vpart_position vp( const_cast<vehicle &>( *veh ), vpart );
1810 if( vp.obstacle_at_part() ) {
1811 return 0;
1812 } else if( vp.part_with_feature( VPFLAG_AISLE, true ) ) {
1813 return 2;
1814 } else {
1815 return 8;
1816 }
1817 }
1818
1819 if( furniture.id ) {
1820 return std::max( terrain.movecost + furniture.movecost, 0 );
1821 }
1822
1823 return std::max( terrain.movecost, 0 );
1824}

References furniture, vpart_position::obstacle_at_part(), vpart_position::part_with_feature(), terrain, and VPFLAG_AISLE.

Referenced by move_cost(), route(), and update_pathfinding_cache().

◆ move_cost_ter_furn() [1/2]

int map::move_cost_ter_furn ( const tripoint p) const

Similar behavior to move_cost(), but ignores vehicles.

Definition at line 1863 of file map.cpp.

1864{
1865 if( !inbounds( p ) ) {
1866 return 0;
1867 }
1868
1869 point l;
1870 submap *const current_submap = get_submap_at( p, l );
1871
1872 const int tercost = current_submap->get_ter( l ).obj().movecost;
1873 if( tercost == 0 ) {
1874 return 0;
1875 }
1876
1877 const int furncost = current_submap->get_furn( l ).obj().movecost;
1878 if( furncost < 0 ) {
1879 return 0;
1880 }
1881
1882 const int cost = tercost + furncost;
1883 return cost > 0 ? cost : 0;
1884}

References submap::get_furn(), get_submap_at(), submap::get_ter(), inbounds(), map_data_common_t::movecost, and int_id< T >::obj().

Referenced by move_cost_ter_furn(), vehicle::part_collision(), passable_ter_furn(), and vehicle_wheel_traction().

◆ move_cost_ter_furn() [2/2]

int map::move_cost_ter_furn ( point  p) const
inline

Definition at line 579 of file map.h.

579 {
580 return move_cost_ter_furn( tripoint( p, abs_sub.z ) );
581 }
int move_cost_ter_furn(const tripoint &p) const
Similar behavior to move_cost(), but ignores vehicles.
Definition: map.cpp:1863

References abs_sub, move_cost_ter_furn(), and tripoint::z.

◆ move_vehicle()

vehicle * map::move_vehicle ( vehicle veh,
const tripoint dp,
const tileray facing 
)

Definition at line 578 of file map.cpp.

579{
580 if( dp == tripoint_zero ) {
581 debugmsg( "Empty displacement vector" );
582 return &veh;
583 } else if( std::abs( dp.x ) > 1 || std::abs( dp.y ) > 1 || std::abs( dp.z ) > 1 ) {
584 debugmsg( "Invalid displacement vector: %d, %d, %d", dp.x, dp.y, dp.z );
585 return &veh;
586 }
587 // Split the movement into horizontal and vertical for easier processing
588 if( dp.xy() != point_zero && dp.z != 0 ) {
589 vehicle *const new_pointer = move_vehicle( veh, tripoint( dp.xy(), 0 ), facing );
590 if( !new_pointer ) {
591 return nullptr;
592 }
593
594 vehicle *const result = move_vehicle( *new_pointer, tripoint( 0, 0, dp.z ), facing );
595 if( !result ) {
596 return nullptr;
597 }
598
599 result->is_falling = false;
600 return result;
601 }
602 const bool vertical = dp.z != 0;
603 // Ensured by the splitting above
604 assert( vertical == ( dp.xy() == point_zero ) );
605
606 const int target_z = dp.z + veh.sm_pos.z;
607 if( target_z < -OVERMAP_DEPTH || target_z > OVERMAP_HEIGHT ) {
608 return &veh;
609 }
610
611 veh.precalc_mounts( 1, veh.skidding ? veh.turn_dir : facing.dir(), veh.pivot_point() );
612
613 // cancel out any movement of the vehicle due only to a change in pivot
614 tripoint dp1 = dp - veh.pivot_displacement();
615
616 if( !vertical ) {
617 veh.adjust_zlevel( 1, dp1 );
618 }
619
620 int impulse = 0;
621
622 std::vector<veh_collision> collisions;
623
624 // Find collisions
625 // Velocity of car before collision
626 // Split into vertical and horizontal movement
627 const int &coll_velocity = vertical ? veh.vertical_velocity : veh.velocity;
628 const int velocity_before = coll_velocity;
629 if( velocity_before == 0 && !veh.is_rotorcraft() && !veh.is_flying_in_air() ) {
630 debugmsg( "%s tried to move %s with no velocity",
631 veh.name, vertical ? "vertically" : "horizontally" );
632 return &veh;
633 }
634
635 bool veh_veh_coll_flag = false;
636 // Try to collide multiple times
637 size_t collision_attempts = 10;
638 do {
639 collisions.clear();
640 veh.collision( collisions, dp1, false );
641
642 // Vehicle collisions
643 std::map<vehicle *, std::vector<veh_collision> > veh_collisions;
644 for( auto &coll : collisions ) {
645 if( coll.type != veh_coll_veh ) {
646 continue;
647 }
648
649 veh_veh_coll_flag = true;
650 // Only collide with each vehicle once
651 veh_collisions[ static_cast<vehicle *>( coll.target ) ].push_back( coll );
652 }
653
654 for( auto &pair : veh_collisions ) {
655 impulse += vehicle_vehicle_collision( veh, *pair.first, pair.second );
656 }
657
658 // Non-vehicle collisions
659 for( const auto &coll : collisions ) {
660 if( coll.type == veh_coll_veh ) {
661 continue;
662 }
663 if( coll.part > veh.part_count() ||
664 veh.part( coll.part ).removed ) {
665 continue;
666 }
667
668 point collision_point = veh.part( coll.part ).mount;
669 const int coll_dmg = coll.imp;
670 // Shock damage, if the target part is a rotor treat as an aimed hit.
671 if( veh.part_info( coll.part ).rotor_diameter() > 0 ) {
672 veh.damage( coll.part, coll_dmg, DT_BASH, true );
673 } else {
674 impulse += coll_dmg;
675 veh.damage( coll.part, coll_dmg, DT_BASH );
676 veh.damage_all( coll_dmg / 2, coll_dmg, DT_BASH, collision_point );
677 }
678 }
679
680 // prevent vehicle bouncing after the first collision
681 if( vertical && velocity_before < 0 && coll_velocity > 0 ) {
682 veh.vertical_velocity = 0; // also affects `coll_velocity` and thus exits the loop
683 }
684
685 } while( collision_attempts-- > 0 && coll_velocity != 0 &&
686 sgn( coll_velocity ) == sgn( velocity_before ) &&
687 !collisions.empty() && !veh_veh_coll_flag );
688
689 const int velocity_after = coll_velocity;
690 bool can_move = velocity_after != 0 && sgn( velocity_after ) == sgn( velocity_before );
691 if( dp.z != 0 && veh.is_rotorcraft() ) {
692 can_move = true;
693 }
694 units::angle coll_turn = 0_degrees;
695 if( impulse > 0 ) {
696 coll_turn = shake_vehicle( veh, velocity_before, facing.dir() );
697 veh.stop_autodriving();
698 const int volume = std::min<int>( 100, std::sqrt( impulse ) );
699 // TODO: Center the sound at weighted (by impulse) average of collisions
701 false, "smash_success", "hit_vehicle" );
702 }
703
704 if( veh_veh_coll_flag ) {
705 // Break here to let the hit vehicle move away
706 return nullptr;
707 }
708
709 // If not enough wheels, mess up the ground a bit.
710 if( !vertical && !veh.valid_wheel_config() && !veh.is_in_water() && !veh.is_flying_in_air() &&
711 dp.z == 0 ) {
712 veh.velocity += veh.velocity < 0 ? 2000 : -2000;
713 for( const auto &p : veh.get_points() ) {
714 const ter_id &pter = ter( p );
715 if( pter == t_dirt || pter == t_grass ) {
716 ter_set( p, t_dirtmound );
717 }
718 }
719 }
720
721 const units::angle last_turn_dec = 1_degrees;
722 if( veh.last_turn < 0_degrees ) {
723 veh.last_turn += last_turn_dec;
724 if( veh.last_turn > -last_turn_dec ) {
725 veh.last_turn = 0_degrees;
726 }
727 } else if( veh.last_turn > 0_degrees ) {
728 veh.last_turn -= last_turn_dec;
729 if( veh.last_turn < last_turn_dec ) {
730 veh.last_turn = 0_degrees;
731 }
732 }
733
734 Character &player_character = get_player_character();
735 const bool seen = sees_veh( player_character, veh, false );
736
737 if( can_move || ( vertical && veh.is_falling ) ) {
738 // Accept new direction
739 if( veh.skidding ) {
740 veh.face.init( veh.turn_dir );
741 } else {
742 veh.face = facing;
743 }
744
745 veh.move = facing;
746 if( coll_turn != 0_degrees ) {
747 veh.skidding = true;
748 veh.turn( coll_turn );
749 }
750 veh.on_move();
751 // Actually change position
752 displace_vehicle( veh, dp1 );
753 veh.shift_zlevel();
754 } else if( !vertical ) {
755 veh.stop();
756 }
758 // If the PC is in the currently moved vehicle, adjust the
759 // view offset.
760 if( g->u.controlling_vehicle && veh_pointer_or_null( veh_at( g->u.pos() ) ) == &veh ) {
761 g->calc_driving_offset( &veh );
762 if( veh.skidding && can_move ) {
763 // TODO: Make skid recovery in air hard
765 }
766 }
767 // Now we're gonna handle traps we're standing on (if we're still moving).
768 if( !vertical && can_move ) {
769 const auto wheel_indices = veh.wheelcache; // Don't use a reference here, it causes a crash.
770
771 // Values to deal with crushing items.
772 // The math needs to be floating-point to work, so the values might as well be.
773 const float vehicle_grounded_wheel_area = static_cast<int>( vehicle_wheel_traction( veh, true ) );
774 const float weight_to_damage_factor = 0.05; // Nobody likes a magic number.
775 const float vehicle_mass_kg = to_kilogram( veh.total_mass() );
776
777 for( auto &w : wheel_indices ) {
778 const tripoint wheel_p = veh.global_part_pos3( w );
779 if( one_in( 2 ) && displace_water( wheel_p ) ) {
780 sounds::sound( wheel_p, 4, sounds::sound_t::movement, _( "splash!" ), false,
781 "environment", "splash" );
782 }
783
784 veh.handle_trap( wheel_p, w );
785 if( !has_flag( "SEALED", wheel_p ) ) {
786 const float wheel_area = veh.part( w ).wheel_area();
787
788 // Damage is calculated based on the weight of the vehicle,
789 // The area of it's wheels, and the area of the wheel running over the items.
790 // This number is multiplied by weight_to_damage_factor to get reasonable results, damage-wise.
791 const int wheel_damage = static_cast<int>( ( ( wheel_area / vehicle_grounded_wheel_area ) *
792 vehicle_mass_kg ) * weight_to_damage_factor );
793
794 //~ %1$s: vehicle name
795 smash_items( wheel_p, wheel_damage, string_format( _( "weight of %1$s" ), veh.disp_name() ),
796 false );
797 }
798 }
799 }
800 if( veh.is_towing() ) {
801 veh.do_towing_move();
802 // veh.do_towing_move() may cancel towing, so we need to recheck is_towing here
803 if( veh.is_towing() && veh.tow_data.get_towed()->tow_cable_too_far() ) {
804 add_msg( m_info, _( "A towing cable snaps off of %s." ),
805 veh.tow_data.get_towed()->disp_name() );
806 veh.tow_data.get_towed()->invalidate_towing( true );
807 }
808 }
809 // Redraw scene, but only if the player is not engaged in an activity and
810 // the vehicle was seen before or after the move.
811 if( !player_character.activity && ( seen || sees_veh( player_character, veh, true ) ) ) {
812 g->invalidate_main_ui_adaptor();
816 }
817 return &veh;
818}
player_activity activity
Definition: character.h:1541
float vehicle_wheel_traction(const vehicle &veh, bool ignore_movement_modifiers=false) const
void smash_items(const tripoint &p, int power, const std::string &cause_message, bool do_destroy)
Tries to smash the items at the given tripoint.
Definition: map.cpp:3052
bool displace_vehicle(vehicle &veh, const tripoint &dp)
Definition: map.cpp:1177
bool displace_water(const tripoint &dp)
Definition: map.cpp:1337
units::angle shake_vehicle(vehicle &veh, int velocity_before, units::angle direction)
vehicle * move_vehicle(vehicle &veh, const tripoint &dp, const tileray &facing)
Definition: map.cpp:578
float vehicle_vehicle_collision(vehicle &veh, vehicle &veh2, const std::vector< veh_collision > &collisions)
Definition: map.cpp:820
void init(point ad)
Definition: tileray.cpp:27
vehicle * get_towed() const
Definition: vehicle.h:159
void turn(units::angle deg)
void adjust_zlevel(int idir=0, const tripoint &offset=tripoint_zero)
bool is_rotorcraft() const
is the vehicle flying? is it a rotorcraft?
Definition: vehicle.cpp:4198
std::set< tripoint > & get_points(bool force_refresh=false)
Definition: vehicle.cpp:6762
bool skidding
Definition: vehicle.h:2024
units::angle last_turn
Definition: vehicle.h:1954
bool is_towing() const
Definition: vehicle.cpp:6036
int vertical_velocity
Definition: vehicle.h:1947
int velocity
Definition: vehicle.h:1943
void damage_all(int dmg1, int dmg2, damage_type type, point impact)
Definition: vehicle.cpp:6444
bool valid_wheel_config() const
Definition: vehicle.cpp:4461
units::mass total_mass() const
Definition: vehicle.cpp:3307
std::vector< int > wheelcache
Definition: vehicle.h:1843
void check_falling_or_floating()
bool is_flying_in_air() const
Definition: vehicle.cpp:4208
towing_data tow_data
Definition: vehicle.h:1969
point pivot_point() const
Definition: vehicle.cpp:5828
int damage(int p, int dmg, damage_type type=DT_BASH, bool aimed=true)
Definition: vehicle.cpp:6365
bool is_in_water(bool deep_water=false) const
is the vehicle mostly in water or mostly on fairly dry land?
Definition: vehicle.cpp:4223
void possibly_recover_from_skid()
tileray move
Definition: vehicle.h:1975
void stop_autodriving(bool apply_brakes=true)
bool collision(std::vector< veh_collision > &colls, const tripoint &dp, bool just_detect, bool bash_floor=false)
void precalc_mounts(int idir, units::angle dir, point pivot)
Definition: vehicle.cpp:3151
bool tow_cable_too_far() const
Definition: vehicle.cpp:6165
std::string disp_name() const
void handle_trap(const tripoint &p, int part)
bool is_falling
Definition: vehicle.h:2030
void shift_zlevel()
units::angle turn_dir
Definition: vehicle.h:1952
point pivot_displacement() const
Definition: vehicle.cpp:3345
void do_towing_move()
Definition: vehicle.cpp:5937
void on_move()
Definition: vehicle.cpp:5278
int rotor_diameter() const
Definition: veh_type.cpp:909
@ m_info
Definition: enums.h:265
constexpr int sgn(const T x)
Definition: enums.h:8
static bool sees_veh(const Creature &c, vehicle &veh, bool force_recalc)
Definition: map.cpp:570
void redraw_invalidated()
Redraw all invalidated windows without invalidating the top window.
Definition: ui_manager.cpp:394
quantity< int, volume_in_milliliter_tag > volume
Definition: units_volume.h:16
constexpr value_type to_kilogram(const quantity< value_type, mass_in_milligram_tag > &v)
Definition: units_mass.h:73
void refresh_display()
Make changes made to the display visible to the user immediately.
static constexpr tripoint tripoint_zero
Definition: point.h:259
int wheel_area() const
Get wheel diameter times wheel width (inches^2) or return 0 if part is not wheel.
bool removed
true if this part is removed.
Definition: vehicle.h:411
point mount
mount point: x is on the forward/backward axis, y is on the left/right axis
Definition: vehicle.h:368
@ veh_coll_veh
Definition: vehicle.h:102

References _, Character::activity, add_msg(), vehicle::adjust_zlevel(), vehicle::check_falling_or_floating(), vehicle::collision(), sounds::combat, vehicle::damage(), vehicle::damage_all(), debugmsg, tileray::dir(), vehicle::disp_name(), displace_vehicle(), displace_water(), vehicle::do_towing_move(), DT_BASH, vehicle::face, g, get_player_character(), vehicle::get_points(), towing_data::get_towed(), vehicle::global_part_pos3(), vehicle::global_pos3(), vehicle::handle_trap(), has_flag(), tileray::init(), inp_mngr, vehicle::invalidate_towing(), vehicle::is_falling, vehicle::is_flying_in_air(), vehicle::is_in_water(), vehicle::is_rotorcraft(), vehicle::is_towing(), vehicle::last_turn, m_info, vehicle_part::mount, vehicle::move, move_vehicle(), sounds::movement, vehicle::name, vehicle::on_move(), one_in(), OVERMAP_HEIGHT, vehicle::part(), vehicle::part_count(), vehicle::part_info(), vehicle::pivot_displacement(), vehicle::pivot_point(), point_zero, vehicle::possibly_recover_from_skid(), vehicle::precalc_mounts(), input_manager::pump_events(), ui_manager::redraw_invalidated(), refresh_display(), vehicle_part::removed, vpart_info::rotor_diameter(), sees_veh(), sgn(), shake_vehicle(), vehicle::shift_zlevel(), vehicle::skidding, vehicle::sm_pos, smash_items(), sounds::sound(), vehicle::stop(), vehicle::stop_autodriving(), string_format(), t_dirt, t_dirtmound, t_grass, ter(), ter_set(), units::to_kilogram(), vehicle::total_mass(), vehicle::tow_cable_too_far(), vehicle::tow_data, tripoint_zero, vehicle::turn(), vehicle::turn_dir, vehicle::valid_wheel_config(), veh_at(), veh_coll_veh, veh_pointer_or_null(), vehicle_vehicle_collision(), vehicle_wheel_traction(), vehicle::velocity, vehicle::vertical_velocity, vehicle_part::wheel_area(), vehicle::wheelcache, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by vehicle::act_on_map(), and move_vehicle().

◆ name() [1/2]

◆ name() [2/2]

std::string map::name ( point  p)
inline

Definition at line 778 of file map.h.

778 {
779 return name( tripoint( p, abs_sub.z ) );
780 }

References abs_sub, name(), and tripoint::z.

◆ obscured_by_vehicle_rotation()

bool map::obscured_by_vehicle_rotation ( const tripoint from,
const tripoint to 
) const

Checks if a rotated vehicle is blocking diagonal vision, tripoints must be adjacent.

Definition at line 6593 of file map.cpp.

6594{
6595 if( !inbounds( from ) || !inbounds( to ) ) {
6596 return false;
6597 }
6598
6599 if( from.z != to.z ) {
6600 //Split it into two checks, one for each z level
6601 tripoint flattened = {from.xy(), to.z};
6602 if( obscured_by_vehicle_rotation( flattened, to ) ) {
6603 return true;
6604 }
6605 }
6606
6607 point delta = to.xy() - from.xy();
6608
6609 auto cache = get_cache( from.z ).vehicle_obscured_cache;
6610
6611 if( delta == point_north_west ) {
6612 return cache[from.x][from.y].nw;
6613 }
6614
6615 if( delta == point_north_east ) {
6616 return cache[from.x][from.y].ne;
6617 }
6618
6619 if( delta == point_south_west ) {
6620 return cache[to.x][to.y].ne;
6621 }
6622 if( delta == point_south_east ) {
6623 return cache[to.x][to.y].nw;
6624 }
6625
6626 return false;
6627}
bool obscured_by_vehicle_rotation(const tripoint &from, const tripoint &to) const
Checks if a rotated vehicle is blocking diagonal vision, tripoints must be adjacent.
Definition: map.cpp:6593
bool nw
Definition: map.h:297

References get_cache(), inbounds(), diagonal_blocks::nw, obscured_by_vehicle_rotation(), point_north_east, point_north_west, point_south_east, point_south_west, level_cache::vehicle_obscured_cache, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by obscured_by_vehicle_rotation(), mattack::riotbot(), Creature::sees(), and sees().

◆ obstacle_coverage()

int map::obstacle_coverage ( const tripoint loc1,
const tripoint loc2 
) const

Returns coverage of target in relation to the observer.

Target is loc2, observer is loc1. First tile from the target is an obstacle, which has the coverage value. If there's no obstacle adjacent to the target - no coverage.

Definition at line 6290 of file map.cpp.

6291{
6292 // Can't hide if you are standing on furniture, or non-flat slowing-down terrain tile.
6293 if( furn( loc2 ).obj().id || ( move_cost( loc2 ) > 2 && !has_flag_ter( TFLAG_FLAT, loc2 ) ) ) {
6294 return 0;
6295 }
6296 const point a( std::abs( loc1.x - loc2.x ) * 2, std::abs( loc1.y - loc2.y ) * 2 );
6297 int offset = std::min( a.x, a.y ) - ( std::max( a.x, a.y ) / 2 );
6298 tripoint obstaclepos;
6299 bresenham( loc2, loc1, offset, 0, [&obstaclepos]( const tripoint & new_point ) {
6300 // Only adjacent tile between you and enemy is checked for cover.
6301 obstaclepos = new_point;
6302 return false;
6303 } );
6304 if( const auto obstacle_f = furn( obstaclepos ) ) {
6305 return obstacle_f->coverage;
6306 }
6307 if( const auto vp = veh_at( obstaclepos ) ) {
6308 if( vp->obstacle_at_part() ) {
6309 return 60;
6310 } else if( !vp->part_with_feature( VPFLAG_AISLE, true ) ) {
6311 return 45;
6312 }
6313 }
6314 return ter( obstaclepos )->coverage;
6315}
@ TFLAG_FLAT
Definition: mapdata.h:317

References a, bresenham(), map_data_common_t::coverage, furn(), has_flag_ter(), move_cost(), ter(), TFLAG_FLAT, veh_at(), VPFLAG_AISLE, tripoint::x, and tripoint::y.

Referenced by Creature::sees().

◆ obstacle_name()

std::string map::obstacle_name ( const tripoint p)

Returns the name of the obstacle at p that might be blocking movement/projectiles/etc.

Note that this only accounts for vehicles, terrain, and furniture.

Definition at line 1393 of file map.cpp.

1394{
1395 if( const cata::optional<vpart_reference> vp = veh_at( p ).obstacle_at_part() ) {
1396 return vp->info().name();
1397 }
1398 return name( p );
1399}

References name(), and veh_at().

Referenced by mattack::longswipe(), avatar_action::move(), and teleport::teleport().

◆ obstructed_by_vehicle_rotation()

bool map::obstructed_by_vehicle_rotation ( const tripoint from,
const tripoint to 
) const

Checks if a rotated vehicle is blocking diagonal movement, tripoints must be adjacent.

Definition at line 6556 of file map.cpp.

6557{
6558 if( !inbounds( from ) || !inbounds( to ) ) {
6559 return false;
6560 }
6561
6562 if( from.z != to.z ) {
6563 //Split it into two checks, one for each z level
6564 tripoint flattened = {from.xy(), to.z};
6565 if( obstructed_by_vehicle_rotation( flattened, to ) ) {
6566 return true;
6567 }
6568 }
6569
6570 point delta = to.xy() - from.xy();
6571
6572 auto cache = get_cache( from.z ).vehicle_obstructed_cache;
6573
6574 if( delta == point_north_west ) {
6575 return cache[from.x][from.y].nw;
6576 }
6577
6578 if( delta == point_north_east ) {
6579 return cache[from.x][from.y].ne;
6580 }
6581
6582 if( delta == point_south_west ) {
6583 return cache[to.x][to.y].ne;
6584 }
6585 if( delta == point_south_east ) {
6586 return cache[to.x][to.y].nw;
6587 }
6588
6589 return false;
6590}
diagonal_blocks vehicle_obstructed_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:339

References get_cache(), inbounds(), diagonal_blocks::nw, obstructed_by_vehicle_rotation(), point_north_east, point_north_west, point_south_east, point_south_west, level_cache::vehicle_obstructed_cache, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by add_splatter_trail(), mattack::boomer(), mattack::boomer_glow(), leap_actor::call(), monster::can_squeeze_to(), choose_adjacent_highlight(), clear_path(), clear_shot_reach(), explosion_handler::do_blast(), mattack::flame(), game::fling_creature(), gas_can_spread_to(), handle_action_menu(), in_spell_aoe(), game::knockback(), mattack::longswipe(), avatar_action::move(), npc::move_to(), obstructed_by_vehicle_rotation(), game::peek(), npc::pick_up_item(), process_fields_in_submap(), projectile_attack(), spell_effect::projectile_attack(), propagate_field(), mattack::ranged_pull(), Character::reach_attack(), route_adjacent(), area_expander::run(), scatter_chunks(), sinkhole_safety_roll(), spell_effect::spell_effect_cone(), and test_passable().

◆ on_vehicle_moved()

void map::on_vehicle_moved ( int  smz)

Callback invoked when a vehicle has moved.

Definition at line 463 of file map.cpp.

464{
468 set_floor_cache_dirty( smz + 1 );
470}

References set_floor_cache_dirty(), set_outside_cache_dirty(), set_pathfinding_cache_dirty(), and set_transparency_cache_dirty().

Referenced by vehicle::act_on_map(), and displace_vehicle().

◆ open_door()

bool map::open_door ( const tripoint p,
bool  inside,
bool  check_only = false 
)

Definition at line 3938 of file map.cpp.

3939{
3940 avatar &you = get_avatar();
3941 const auto &ter = this->ter( p ).obj();
3942 const auto &furn = this->furn( p ).obj();
3943 if( ter.open ) {
3944 if( has_flag( "OPENCLOSE_INSIDE", p ) && !inside ) {
3945 return false;
3946 }
3947
3948 if( !check_only ) {
3949 sounds::sound( p, 6, sounds::sound_t::movement, _( "swish" ), true,
3950 "open_door", ter.id.str() );
3951 ter_set( p, ter.open );
3952
3953 if( ( you.has_trait( trait_id( "SCHIZOPHRENIC" ) ) || you.has_artifact_with( AEP_SCHIZO ) )
3954 && one_in( 50 ) && !ter.has_flag( "TRANSPARENT" ) ) {
3955 tripoint mp = p + -2 * you.pos().xy() + tripoint( 2 * p.x, 2 * p.y, p.z );
3956 g->spawn_hallucination( mp );
3957 }
3958 }
3959
3960 return true;
3961 } else if( furn.open ) {
3962 if( has_flag( "OPENCLOSE_INSIDE", p ) && !inside ) {
3963 return false;
3964 }
3965
3966 if( !check_only ) {
3967 sounds::sound( p, 6, sounds::sound_t::movement, _( "swish" ), true,
3968 "open_door", furn.id.str() );
3969 furn_set( p, furn.open );
3970 }
3971
3972 return true;
3973 } else if( const optional_vpart_position vp = veh_at( p ) ) {
3974 int openable = vp->vehicle().next_part_to_open( vp->part_index(), true );
3975 if( openable >= 0 ) {
3976 if( !check_only ) {
3977 if( !vp->vehicle().handle_potential_theft( you ) ) {
3978 return false;
3979 }
3980 vp->vehicle().open_all_at( openable );
3981 }
3982
3983 return true;
3984 }
3985
3986 return false;
3987 }
3988
3989 return false;
3990}
avatar & get_avatar()
Definition: avatar.cpp:104
virtual bool has_artifact_with(art_effect_passive effect) const
Definition: character.cpp:3181
bool has_trait(const trait_id &b) const override
Returns true if the player has the entered trait.
Definition: mutation.cpp:101
Definition: avatar.h:55
@ AEP_SCHIZO
Definition: enums.h:128

References _, AEP_SCHIZO, furn(), furn_set(), g, get_avatar(), Character::has_artifact_with(), has_flag(), Character::has_trait(), int_id< T >::id(), sounds::movement, int_id< T >::obj(), one_in(), Character::pos(), sounds::sound(), string_id< T >::str(), ter(), ter_set(), veh_at(), tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by can_interact_at(), npc::can_open_door(), iexamine::door_peephole(), monster::move(), avatar_action::move(), npc::move_to(), open(), and rate_location().

◆ operator=() [1/2]

map & map::operator= ( const map )
delete

◆ operator=() [2/2]

map & map::operator= ( map &&  )
default

◆ partial_con_at()

partial_con * map::partial_con_at ( const tripoint p)

Definition at line 5214 of file map.cpp.

5215{
5216 if( !inbounds( p ) ) {
5217 return nullptr;
5218 }
5219 point l;
5220 submap *const current_submap = get_submap_at( p, l );
5221 auto it = current_submap->partial_constructions.find( tripoint( l, p.z ) );
5222 if( it != current_submap->partial_constructions.end() ) {
5223 return &it->second;
5224 }
5225 return nullptr;
5226}
std::map< tripoint, partial_con > partial_constructions
Definition: submap.h:219

References get_submap_at(), inbounds(), submap::partial_constructions, and tripoint::z.

Referenced by activity_handlers::build_do_turn(), can_do_activity_there(), complete_construction(), generic_multi_activity_check_requirement(), generic_multi_activity_do(), generic_multi_activity_locations(), player_activity::get_progress_message(), place_construction(), game::print_trap_info(), and iexamine::trap().

◆ partial_con_remove()

void map::partial_con_remove ( const tripoint p)

Definition at line 5228 of file map.cpp.

5229{
5230 if( !inbounds( p ) ) {
5231 return;
5232 }
5233 point l;
5234 submap *const current_submap = get_submap_at( p, l );
5235 current_submap->partial_constructions.erase( tripoint( l, p.z ) );
5236}

References get_submap_at(), inbounds(), submap::partial_constructions, and tripoint::z.

Referenced by complete_construction(), and iexamine::trap().

◆ partial_con_set()

void map::partial_con_set ( const tripoint p,
const partial_con con 
)

Definition at line 5238 of file map.cpp.

5239{
5240 if( !inbounds( p ) ) {
5241 return;
5242 }
5243 point l;
5244 submap *const current_submap = get_submap_at( p, l );
5245 if( !current_submap->partial_constructions.emplace( tripoint( l, p.z ), con ).second ) {
5246 debugmsg( "set partial con on top of terrain which already has a partial con" );
5247 }
5248}

References debugmsg, get_submap_at(), inbounds(), submap::partial_constructions, and tripoint::z.

Referenced by construction_activity(), and place_construction().

◆ passable() [1/2]

◆ passable() [2/2]

bool map::passable ( point  p) const
inline

Definition at line 570 of file map.h.

570 {
571 return passable( tripoint( p, abs_sub.z ) );
572 }

References abs_sub, passable(), and tripoint::z.

◆ passable_ter_furn()

bool map::passable_ter_furn ( const tripoint p) const

Definition at line 1891 of file map.cpp.

1892{
1893 return move_cost_ter_furn( p ) != 0;
1894}

References move_cost_ter_furn().

Referenced by impassable_ter_furn(), and avatar_action::move().

◆ pl_line_of_sight()

bool map::pl_line_of_sight ( const tripoint t,
int  max_range 
) const

Uses the map cache to tell if the player could see the given square.

pl_sees implies pl_line_of_sight Used for infrared.

Definition at line 795 of file lightmap.cpp.

796{
797 if( !inbounds( t ) ) {
798 return false;
799 }
800
801 if( max_range >= 0 && square_dist( t, g->u.pos() ) > max_range ) {
802 // Out of range!
803 return false;
804 }
805
806 const auto &map_cache = get_cache_ref( t.z );
807 // Any epsilon > 0 is fine - it means lightmap processing visited the point
808 return map_cache.seen_cache[t.x][t.y] > 0.0f ||
809 map_cache.camera_cache[t.x][t.y] > 0.0f;
810}

References g, get_cache_ref(), inbounds(), square_dist(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by get_heat_radiation(), and Character::sees_with_infrared().

◆ pl_sees()

bool map::pl_sees ( const tripoint t,
int  max_range 
) const

Whether the player character (g->u) can see the given square (local map coordinates).

This only checks the transparency of the path to the target, the light level is not checked.

Parameters
tTarget point to look at
max_rangeAll squares that are further away than this are invisible. Ignored if smaller than 0.

Definition at line 777 of file lightmap.cpp.

778{
779 if( !inbounds( t ) ) {
780 return false;
781 }
782
783 if( max_range >= 0 && square_dist( t, g->u.pos() ) > max_range ) {
784 return false; // Out of range!
785 }
786
787 const auto &map_cache = get_cache_ref( t.z );
788 const apparent_light_info a = apparent_light_helper( map_cache, t );
789 const float light_at_player = map_cache.lm[g->u.posx()][g->u.posy()].max();
790 return !a.obstructed &&
791 ( a.apparent_light >= g->u.get_vision_threshold( light_at_player ) ||
792 map_cache.sm[t.x][t.y] > 0.0 );
793}

References a, apparent_light_helper(), g, get_cache_ref(), inbounds(), square_dist(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by computer_session::action_irradiator(), sounds::process_sound_markers(), and Character::sees().

◆ place_gas_pump() [1/2]

void map::place_gas_pump ( point  p,
int  charges 
)

Definition at line 5485 of file mapgen.cpp.

5486{
5487 place_gas_pump( p, charges, one_in( 4 ) ? "diesel" : "gasoline" );
5488}
void place_gas_pump(point p, int charges, const std::string &fuel_type)
Definition: mapgen.cpp:5477

References one_in(), and place_gas_pump().

◆ place_gas_pump() [2/2]

void map::place_gas_pump ( point  p,
int  charges,
const std::string &  fuel_type 
)

Definition at line 5477 of file mapgen.cpp.

5478{
5479 item fuel( fuel_type, calendar::start_of_cataclysm );
5480 fuel.charges = charges;
5481 add_item( p, fuel );
5482 ter_set( p, ter_id( fuel.fuel_pump_terrain() ) );
5483}

References add_item(), item::charges, item::fuel_pump_terrain(), calendar::start_of_cataclysm, ter_id, and ter_set().

Referenced by jmapgen_gaspump::apply(), mapgen_tutorial(), and place_gas_pump().

◆ place_items() [1/2]

std::vector< item * > map::place_items ( const item_group_id loc,
int  chance,
const tripoint p1,
const tripoint p2,
bool  ongrass,
const time_point turn,
int  magazine = 0,
int  ammo = 0 
)

Place items from item group in the rectangle f - t.

Several items may be spawned on different places. Several items may spawn at once (at one place) when the item group says so (uses item_group::items_from which may return several items at once).

Parameters
locCurrent location of items to be placed
chanceChance for more items. A chance of 100 creates 1 item all the time, otherwise it's the chance that more items will be created (place items until the random roll with that chance fails). The chance is used for the first item as well, so it may not spawn an item at all. Values <= 0 or > 100 are invalid.
p1One corner of rectangle in which to spawn items
p2Second corner of rectangle in which to spawn items
ongrassIf false the items won't spawn on flat terrain (grass, floor, ...).
turnThe birthday that the created items shall have.
magazinepercentage chance item will contain the default magazine
ammopercentage chance item will be filled with default ammo
Returns
vector containing all placed items

Definition at line 5550 of file mapgen.cpp.

5554{
5555 // TODO: implement for 3D
5556 std::vector<item *> res;
5557
5558 if( chance > 100 || chance <= 0 ) {
5559 debugmsg( "map::place_items() called with an invalid chance (%d)", chance );
5560 return res;
5561 }
5562 if( !item_group::group_is_defined( loc ) ) {
5563 // TODO: fix point types
5565 const oter_id &oid = overmap_buffer.ter( omt );
5566 debugmsg( "place_items: invalid item group '%s', om_terrain = '%s' (%s)",
5567 loc.c_str(), oid.id().c_str(), oid->get_mapgen_id().c_str() );
5568 return res;
5569 }
5570
5571 const float spawn_rate = get_option<float>( "ITEM_SPAWNRATE" );
5572 int spawn_count = roll_remainder( chance * spawn_rate / 100.0f );
5573 for( int i = 0; i < spawn_count; i++ ) {
5574 // Might contain one item or several that belong together like guns & their ammo
5575 int tries = 0;
5576 auto is_valid_terrain = [this, ongrass]( point p ) {
5577 auto &terrain = ter( p ).obj();
5578 return terrain.movecost == 0 &&
5579 !terrain.has_flag( "PLACE_ITEM" ) &&
5580 !ongrass &&
5581 !terrain.has_flag( "FLAT" );
5582 };
5583
5584 point p;
5585 do {
5586 p.x = rng( p1.x, p2.x );
5587 p.y = rng( p1.y, p2.y );
5588 tries++;
5589 } while( is_valid_terrain( p ) && tries < 20 );
5590 if( tries < 20 ) {
5591 auto put = put_items_from_loc( loc, tripoint( p, abs_sub.z ), turn );
5592 res.insert( res.end(), put.begin(), put.end() );
5593 }
5594 }
5595 for( auto e : res ) {
5596 if( e->is_tool() || e->is_gun() || e->is_magazine() ) {
5597 if( rng( 0, 99 ) < magazine && !e->magazine_integral() && !e->magazine_current() ) {
5598 e->put_in( item( e->magazine_default(), e->birthday() ) );
5599 }
5600 if( rng( 0, 99 ) < ammo && e->ammo_remaining() == 0 ) {
5601 e->ammo_set( e->ammo_default(), e->ammo_capacity() );
5602 }
5603 }
5604 }
5605 return res;
5606}
constexpr scale omt
Definition: coordinates.h:32
bool group_is_defined(const item_group_id &group_id)
Check whether an item group of the given id exists.
Definition: item_group.cpp:603

References abs_sub, string_id< T >::c_str(), debugmsg, get_abs_sub(), oter_t::get_mapgen_id(), item_group::group_is_defined(), int_id< T >::id(), int_id< T >::obj(), coords::omt, overmap_buffer, put_items_from_loc(), rng(), roll_remainder(), sm_to_omt_copy(), ter(), overmapbuffer::ter(), terrain, calendar::turn, point::x, tripoint::x, point::y, tripoint::y, and tripoint::z.

Referenced by jmapgen_item_group::apply(), draw_lab(), draw_mine(), draw_office_tower(), draw_slimepit(), mapgen_ants_food(), mapgen_ants_generic(), mapgen_ants_larvae(), mapgen_ants_queen(), mapgen_cavern(), mapgen_crater(), mapgen_field(), mapgen_forest(), mapgen_forest_trail_curved(), mapgen_forest_trail_four_way(), mapgen_forest_trail_straight(), mapgen_forest_trail_tee(), mapgen_highway(), mapgen_hive(), mapgen_parking_lot(), mapgen_road(), mapgen_sewer_curved(), mapgen_sewer_four_way(), mapgen_sewer_straight(), mapgen_sewer_tee(), MapExtras::mx_collegekids(), MapExtras::mx_drugdeal(), MapExtras::mx_house_spider(), MapExtras::mx_house_wasp(), MapExtras::mx_military(), MapExtras::mx_minefield(), MapExtras::mx_roadblock(), MapExtras::mx_roadworks(), MapExtras::mx_science(), MapExtras::mx_supplydrop(), place_items(), place_vending(), mission_start::ranch_nurse_8(), mission_start::ranch_scavenger_1(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), and science_room().

◆ place_items() [2/2]

std::vector< item * > map::place_items ( const item_group_id loc,
int  chance,
point  p1,
point  p2,
bool  ongrass,
const time_point turn,
int  magazine = 0,
int  ammo = 0 
)
inline

Definition at line 1306 of file map.h.

1308 {
1309 return place_items( loc, chance, tripoint( p1, abs_sub.z ), tripoint( p2, abs_sub.z ), ongrass,
1310 turn, magazine, ammo );
1311 }

References abs_sub, place_items(), calendar::turn, and tripoint::z.

◆ place_npc()

character_id map::place_npc ( point  p,
const string_id< npc_template > &  type,
bool  force = false 
)

Definition at line 5518 of file mapgen.cpp.

5519{
5520 if( !force && !get_option<bool>( "STATIC_NPC" ) ) {
5521 return character_id(); //Do not generate an npc.
5522 }
5523 shared_ptr_fast<npc> temp = make_shared_fast<npc>();
5524 temp->load_npc_template( type );
5525 temp->spawn_at_precise( { abs_sub.xy() }, { p, abs_sub.z } );
5526 temp->toggle_trait( trait_NPC_STATIC_NPC );
5527 overmap_buffer.insert_npc( temp );
5528 return temp->getID();
5529}
void insert_npc(const shared_ptr_fast< npc > &who)
Adds the npc to an overmap ( based on the npcs current location ) and stores it there.
static const trait_id trait_NPC_STATIC_NPC("NPC_STATIC_NPC")
std::shared_ptr< T > shared_ptr_fast
Definition: memory_fast.h:16

References abs_sub, character_id, overmapbuffer::insert_npc(), overmap_buffer, trait_NPC_STATIC_NPC, type, tripoint::xy(), and tripoint::z.

Referenced by jmapgen_npc::apply(), mapgen_hive(), MapExtras::mx_bandits_block(), MapExtras::mx_looters(), MapExtras::mx_marloss_pilgrimage(), mission_start::ranch_nurse_9(), and place_npc_iuse::use().

◆ place_spawns()

void map::place_spawns ( const mongroup_id group,
int  chance,
point  p1,
point  p2,
float  density,
bool  individual = false,
bool  friendly = false,
const std::string &  name = "NONE",
int  mission_id = -1 
)

Definition at line 5427 of file mapgen.cpp.

5430{
5431 if( !group.is_valid() ) {
5432 // TODO: fix point types
5434 const oter_id &oid = overmap_buffer.ter( omt );
5435 debugmsg( "place_spawns: invalid mongroup '%s', om_terrain = '%s' (%s)", group.c_str(),
5436 oid.id().c_str(), oid->get_mapgen_id().c_str() );
5437 return;
5438 }
5439
5440 // Set chance to be 1 or less to guarantee spawn, else set higher than 1
5441 if( !one_in( chance ) ) {
5442 return;
5443 }
5444
5445 float spawn_density = 1.0f;
5447 spawn_density = get_option< float >( "SPAWN_ANIMAL_DENSITY" );
5448 } else {
5449 spawn_density = get_option< float >( "SPAWN_DENSITY" );
5450 }
5451
5452 float multiplier = density * spawn_density;
5453 // Only spawn 1 creature if individual flag set, else scale by density
5454 float thenum = individual ? 1 : ( multiplier * rng_float( 10.0f, 50.0f ) );
5455 int num = roll_remainder( thenum );
5456
5457 // GetResultFromGroup decrements num
5458 while( num > 0 ) {
5459 int tries = 10;
5460 point p;
5461
5462 // Pick a spot for the spawn
5463 do {
5464 p.x = rng( p1.x, p2.x );
5465 p.y = rng( p1.y, p2.y );
5466 tries--;
5467 } while( impassable( p ) && tries > 0 );
5468
5469 // Pick a monster type
5471
5472 add_spawn( spawn_details.name, spawn_details.pack_size, { p, abs_sub.z },
5473 friendly, -1, mission_id, name );
5474 }
5475}
group
Definition: sounds.h:125

References add_spawn(), string_id< T >::c_str(), debugmsg, friendly, get_abs_sub(), oter_t::get_mapgen_id(), MonsterGroupManager::GetResultFromGroup(), int_id< T >::id(), impassable(), MonsterGroupManager::is_animal(), name(), MonsterGroupResult::name, num, coords::omt, one_in(), overmap_buffer, MonsterGroupResult::pack_size, rng(), rng_float(), roll_remainder(), sm_to_omt_copy(), overmapbuffer::ter(), point::x, and point::y.

Referenced by add_monsters(), jmapgen_monster_group::apply(), create_anomaly(), draw_lab(), draw_mine(), draw_office_tower(), draw_slimepit(), draw_temple(), draw_triffid(), mapgen_road(), MapExtras::mx_collegekids(), MapExtras::mx_corpses(), MapExtras::mx_drugdeal(), MapExtras::mx_military(), MapExtras::mx_pond(), MapExtras::mx_portal(), MapExtras::mx_portal_in(), MapExtras::mx_science(), and science_room().

◆ place_toilet()

void map::place_toilet ( point  p,
int  charges = 6 * 4 
)

Definition at line 5490 of file mapgen.cpp.

5491{
5492 item water( "water", calendar::start_of_cataclysm );
5493 water.charges = charges;
5494 add_item( p, water );
5495 furn_set( p, f_toilet );
5496}

References add_item(), item::charges, f_toilet, furn_set(), and calendar::start_of_cataclysm.

Referenced by jmapgen_toilet::apply(), and mapf::formatted_set_simple().

◆ place_vending()

void map::place_vending ( point  p,
const item_group_id type,
bool  reinforced = false 
)

Definition at line 5498 of file mapgen.cpp.

5499{
5500 if( reinforced ) {
5502 place_items( type, 100, p, p, false, calendar::start_of_cataclysm );
5503 } else {
5504 if( one_in( 2 ) ) {
5505 furn_set( p, f_vending_o );
5506 for( const auto &loc : points_in_radius( { p, abs_sub.z }, 1 ) ) {
5507 if( one_in( 4 ) ) {
5508 spawn_item( loc, "glass_shard", rng( 1, 2 ) );
5509 }
5510 }
5511 } else {
5512 furn_set( p, f_vending_c );
5513 place_items( type, 100, p, p, false, calendar::start_of_cataclysm );
5514 }
5515 }
5516}
furn_id f_vending_o
Definition: mapdata.cpp:1111
furn_id f_vending_reinforced
Definition: mapdata.cpp:1134
furn_id f_vending_c
Definition: mapdata.cpp:1111

References abs_sub, f_vending_c, f_vending_o, f_vending_reinforced, furn_set(), one_in(), place_items(), points_in_radius(), rng(), spawn_item(), calendar::start_of_cataclysm, type, and tripoint::z.

Referenced by jmapgen_vending_machine::apply().

◆ player_in_field()

void map::player_in_field ( player u)
protected

Definition at line 1224 of file map_field.cpp.

1225{
1226 // A copy of the current field for reference. Do not add fields to it, use map::add_field
1227 field &curfield = get_field( u.pos() );
1228 // Are we inside?
1229 bool inside = false;
1230 // If we are in a vehicle figure out if we are inside (reduces effects usually)
1231 // and what part of the vehicle we need to deal with.
1232 if( u.in_vehicle ) {
1233 if( const optional_vpart_position vp = veh_at( u.pos() ) ) {
1234 inside = vp->is_inside();
1235 }
1236 }
1237
1238 // Iterate through all field effects on this tile.
1239 // Do not remove the field with remove_field, instead set it's intensity to 0. It will be removed
1240 // later by the field processing, which will also adjust field_count accordingly.
1241 for( auto &field_list_it : curfield ) {
1242 field_entry &cur = field_list_it.second;
1243 if( !cur.is_field_alive() ) {
1244 continue;
1245 }
1246
1247 // Do things based on what field effect we are currently in.
1248 const field_type_id ft = cur.get_field_type();
1249 if( ft == fd_web ) {
1250 // If we are in a web, can't walk in webs or are in a vehicle, get webbed maybe.
1251 // Moving through multiple webs stacks the effect.
1252 if( !u.has_trait( trait_WEB_WALKER ) && !u.in_vehicle ) {
1253 // Between 5 and 15 minus your current web level.
1254 u.add_effect( effect_webbed, 1_turns, num_bp, cur.get_field_intensity() );
1255 // It is spent.
1256 cur.set_field_intensity( 0 );
1257 continue;
1258 // If you are in a vehicle destroy the web.
1259 // It should of been destroyed when you ran over it anyway.
1260 } else if( u.in_vehicle ) {
1261 cur.set_field_intensity( 0 );
1262 continue;
1263 }
1264 }
1265 if( ft == fd_acid ) {
1266 // Assume vehicles block acid damage entirely,
1267 // you're certainly not standing in it.
1268 if( !u.in_vehicle && !u.has_trait( trait_ACIDPROOF ) ) {
1269 int total_damage = 0;
1270 total_damage += burn_body_part( u, cur, bp_foot_l, 2 );
1271 total_damage += burn_body_part( u, cur, bp_foot_r, 2 );
1272 const bool on_ground = u.is_on_ground();
1273 if( on_ground ) {
1274 // Apply the effect to the remaining body parts
1275 total_damage += burn_body_part( u, cur, bp_leg_l, 2 );
1276 total_damage += burn_body_part( u, cur, bp_leg_r, 2 );
1277 total_damage += burn_body_part( u, cur, bp_hand_l, 2 );
1278 total_damage += burn_body_part( u, cur, bp_hand_r, 2 );
1279 total_damage += burn_body_part( u, cur, bp_torso, 2 );
1280 // Less arms = less ability to keep upright
1281 if( ( !u.has_two_arms() && one_in( 4 ) ) || one_in( 2 ) ) {
1282 total_damage += burn_body_part( u, cur, bp_arm_l, 1 );
1283 total_damage += burn_body_part( u, cur, bp_arm_r, 1 );
1284 total_damage += burn_body_part( u, cur, bp_head, 1 );
1285 }
1286 }
1287
1288 if( on_ground && total_damage > 0 ) {
1289 u.add_msg_player_or_npc( m_bad, _( "The acid burns your body!" ),
1290 _( "The acid burns <npcname>s body!" ) );
1291 } else if( total_damage > 0 ) {
1292 u.add_msg_player_or_npc( m_bad, _( "The acid burns your legs and feet!" ),
1293 _( "The acid burns <npcname>s legs and feet!" ) );
1294 } else if( on_ground ) {
1295 u.add_msg_if_player( m_warning, _( "You're lying in a pool of acid" ) );
1296 } else {
1297 u.add_msg_if_player( m_warning, _( "You're standing in a pool of acid" ) );
1298 }
1299
1300 u.check_dead_state();
1301 }
1302 }
1303 if( ft == fd_sap ) {
1304 // Sap does nothing to cars.
1305 if( !u.in_vehicle ) {
1306 // Use up sap.
1308 }
1309 }
1310 if( ft == fd_sludge ) {
1311 // Sludge is on the ground, but you are above the ground when boarded on a vehicle
1312 if( !u.in_vehicle ) {
1313 u.add_msg_if_player( m_bad, _( "The sludge is thick and sticky. You struggle to pull free." ) );
1314 u.moves -= cur.get_field_intensity() * 300;
1315 cur.set_field_intensity( 0 );
1316 }
1317 }
1318 if( ft == fd_fire ) {
1319 // Heatsink or suit prevents ALL fire damage.
1321
1322 // To modify power of a field based on... whatever is relevant for the effect.
1323 int adjusted_intensity = cur.get_field_intensity();
1324 // Burn the player. Less so if you are in a car or ON a car.
1325 if( u.in_vehicle ) {
1326 if( inside ) {
1327 adjusted_intensity -= 2;
1328 } else {
1329 adjusted_intensity -= 1;
1330 }
1331 }
1332
1333 if( adjusted_intensity >= 1 ) {
1334 // Burn message by intensity
1335 static const std::array<std::string, 4> player_burn_msg = { {
1336 translate_marker( "You burn your legs and feet!" ),
1337 translate_marker( "You're burning up!" ),
1338 translate_marker( "You're set ablaze!" ),
1339 translate_marker( "Your whole body is burning!" )
1340 }
1341 };
1342 static const std::array<std::string, 4> npc_burn_msg = { {
1343 translate_marker( "<npcname> burns their legs and feet!" ),
1344 translate_marker( "<npcname> is burning up!" ),
1345 translate_marker( "<npcname> is set ablaze!" ),
1346 translate_marker( "<npcname>s whole body is burning!" )
1347 }
1348 };
1349 static const std::array<std::string, 4> player_warn_msg = { {
1350 translate_marker( "You're standing in a fire!" ),
1351 translate_marker( "You're waist-deep in a fire!" ),
1352 translate_marker( "You're surrounded by raging fire!" ),
1353 translate_marker( "You're lying in fire!" )
1354 }
1355 };
1356
1357 const int burn_min = adjusted_intensity;
1358 const int burn_max = 3 * adjusted_intensity + 3;
1359 std::list<bodypart_id> parts_burned;
1360 int msg_num = adjusted_intensity - 1;
1361 if( !u.is_on_ground() ) {
1362 switch( adjusted_intensity ) {
1363 case 3:
1364 parts_burned.push_back( bodypart_id( "hand_l" ) );
1365 parts_burned.push_back( bodypart_id( "hand_r" ) );
1366 parts_burned.push_back( bodypart_id( "arm_l" ) );
1367 parts_burned.push_back( bodypart_id( "arm_r" ) );
1368 /* fallthrough */
1369 case 2:
1370 parts_burned.push_back( bodypart_id( "torso" ) );
1371 /* fallthrough */
1372 case 1:
1373 parts_burned.push_back( bodypart_id( "foot_l" ) );
1374 parts_burned.push_back( bodypart_id( "foot_r" ) );
1375 parts_burned.push_back( bodypart_id( "leg_l" ) );
1376 parts_burned.push_back( bodypart_id( "leg_r" ) );
1377 }
1378 } else {
1379 // Lying in the fire is BAAAD news, hits every body part.
1380 msg_num = 3;
1381 const std::vector<bodypart_id> &all_parts = u.get_all_body_parts();
1382 // HACK: Skip num_bp part
1383 for( auto bp : all_parts ) {
1384 if( bp->token != num_bp ) {
1385 parts_burned.push_back( bp );
1386 }
1387 }
1388 }
1389
1390 int total_damage = 0;
1391 for( const bodypart_id part_burned : parts_burned ) {
1392 const dealt_damage_instance dealt = u.deal_damage( nullptr, part_burned,
1393 damage_instance( DT_HEAT, rng( burn_min, burn_max ) ) );
1394 total_damage += dealt.type_damage( DT_HEAT );
1395 }
1396 if( total_damage > 0 ) {
1397 u.add_msg_player_or_npc( m_bad, _( player_burn_msg[msg_num] ), _( npc_burn_msg[msg_num] ) );
1398 } else {
1399 u.add_msg_if_player( m_warning, _( player_warn_msg[msg_num] ) );
1400 }
1401 u.check_dead_state();
1402 }
1403 }
1404
1405 }
1406 if( ft == fd_tear_gas ) {
1407 // Tear gas will both give you teargas disease and/or blind you.
1408 if( ( cur.get_field_intensity() > 1 || !one_in( 3 ) ) && ( !inside || one_in( 3 ) ) ) {
1409 u.add_env_effect( effect_teargas, bp_mouth, 5, 20_seconds );
1410 }
1411 if( cur.get_field_intensity() > 1 && ( !inside || one_in( 3 ) ) ) {
1412 u.add_env_effect( effect_blind, bp_eyes, cur.get_field_intensity() * 2, 10_seconds );
1413 }
1414 }
1415 if( ft == fd_fungal_haze ) {
1416 if( !u.has_trait( trait_M_IMMUNE ) && ( !inside || one_in( 4 ) ) ) {
1417 u.add_env_effect( effect_fungus, bp_mouth, 4, 10_minutes, num_bp );
1418 u.add_env_effect( effect_fungus, bp_eyes, 4, 10_minutes, num_bp );
1419 }
1420 }
1421 if( ft == fd_dazzling ) {
1422 if( cur.get_field_intensity() > 1 || one_in( 5 ) ) {
1423 u.add_env_effect( effect_blind, bp_eyes, 10, 10_turns );
1424 } else {
1425 u.add_env_effect( effect_blind, bp_eyes, 2, 2_turns );
1426 }
1427 }
1428
1429 if( cur.extra_radiation_min() > 0 ) {
1430 // Get irradiated by the nuclear fallout.
1431 const float rads = rng( cur.extra_radiation_min() + 1,
1432 cur.extra_radiation_max() * ( cur.extra_radiation_max() + 1 ) );
1433 const bool rad_proof = !u.irradiate( rads );
1434 // TODO: Reduce damage for rad resistant?
1435 if( cur.radiation_hurt_damage_min() > 0 && !rad_proof ) {
1437 u.hurtall( rng( cur.radiation_hurt_damage_min(), cur.radiation_hurt_damage_max() ), nullptr );
1438 }
1439 }
1440 if( ft == fd_flame_burst ) {
1441 // A burst of flame? Only hits the legs and torso.
1442 if( !inside ) {
1443 // Fireballs can't touch you inside a car.
1444 // Heatsink or suit stops fire.
1445 if( !u.has_active_bionic( bio_heatsink ) &&
1447 u.add_msg_player_or_npc( m_bad, _( "You're torched by flames!" ),
1448 _( "<npcname> is torched by flames!" ) );
1449 u.deal_damage( nullptr, bodypart_id( "leg_l" ), damage_instance( DT_HEAT, rng( 2, 6 ) ) );
1450 u.deal_damage( nullptr, bodypart_id( "leg_r" ), damage_instance( DT_HEAT, rng( 2, 6 ) ) );
1451 u.deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_HEAT, rng( 4, 9 ) ) );
1452 u.check_dead_state();
1453 } else {
1454 u.add_msg_player_or_npc( _( "These flames do not burn you." ),
1455 _( "Those flames do not burn <npcname>." ) );
1456 }
1457 }
1458 }
1459 if( ft == fd_electricity ) {
1460 // Small universal damage based on intensity, only if not electroproofed.
1461 if( !u.is_elec_immune() ) {
1462 int total_damage = 0;
1463 for( size_t i = 0; i < num_hp_parts; i++ ) {
1464 const bodypart_id bp = convert_bp( player::hp_to_bp( static_cast<hp_part>( i ) ) ).id();
1465 const int dmg = rng( 1, cur.get_field_intensity() );
1466 total_damage += u.deal_damage( nullptr, bp, damage_instance( DT_ELECTRIC, dmg ) ).total_damage();
1467 }
1468
1469 if( total_damage > 0 ) {
1471 u.add_msg_player_or_npc( m_bad, _( "You're painfully electrocuted!" ),
1472 _( "<npcname> is shocked!" ) );
1473 u.mod_pain( total_damage / 2 );
1474 } else {
1475 u.add_msg_player_or_npc( m_bad, _( "You're shocked!" ), _( "<npcname> is shocked!" ) );
1476 }
1477 } else {
1478 u.add_msg_player_or_npc( _( "The electric cloud doesn't affect you." ),
1479 _( "The electric cloud doesn't seem to affect <npcname>." ) );
1480 }
1481 }
1482 }
1483 if( ft == fd_fatigue ) {
1484 // Assume the rift is on the ground for now to prevent issues with the player being unable access vehicle controls on the same tile due to teleportation.
1485 if( !u.in_vehicle ) {
1486 // Teleports you... somewhere.
1487 if( rng( 0, 2 ) < cur.get_field_intensity() && u.is_player() ) {
1488 add_msg( m_bad, _( "You're violently teleported!" ) );
1489 u.hurtall( cur.get_field_intensity(), nullptr );
1490 teleport::teleport( u );
1491 }
1492 }
1493 }
1494 // Why do these get removed???
1495 // Stepping on a shock vent shuts it down.
1496 if( ft == fd_shock_vent || ft == fd_acid_vent ) {
1497 cur.set_field_intensity( 0 );
1498 }
1499 if( ft == fd_bees ) {
1500 // Player is immune to bees while underwater.
1501 if( !u.is_underwater() ) {
1502 const int intensity = cur.get_field_intensity();
1503 // Bees will try to sting you in random body parts, up to 8 times.
1504 for( int i = 0; i < rng( 1, 7 ); i++ ) {
1506 int sum_cover = 0;
1507 for( const item &i : u.worn ) {
1508 if( i.covers( bp->token ) ) {
1509 sum_cover += i.get_coverage();
1510 }
1511 }
1512 // Get stung if [clothing on a body part isn't thick enough (like t-shirt) OR clothing covers less than 100% of body part]
1513 // AND clothing on affected body part has low environmental protection value
1514 if( ( u.get_armor_cut( bp ) <= 1 || ( sum_cover < 100 && x_in_y( 100 - sum_cover, 100 ) ) ) &&
1515 u.add_env_effect( effect_stung, bp->token, intensity, 9_minutes ) ) {
1516 u.add_msg_if_player( m_bad, _( "The bees sting you in %s!" ),
1517 body_part_name_accusative( bp->token ) );
1518 }
1519 }
1520 }
1521 }
1522 if( ft == fd_incendiary ) {
1523 // Mysterious incendiary substance melts you horribly.
1524 if( u.has_trait( trait_M_SKIN2 ) ||
1525 u.has_trait( trait_M_SKIN3 ) ||
1526 cur.get_field_intensity() == 1 ) {
1527 u.add_msg_player_or_npc( m_bad, _( "The incendiary burns you!" ),
1528 _( "The incendiary burns <npcname>!" ) );
1529 u.hurtall( rng( 1, 3 ), nullptr );
1530 } else {
1531 u.add_msg_player_or_npc( m_bad, _( "The incendiary melts into your skin!" ),
1532 _( "The incendiary melts into <npcname>s skin!" ) );
1533 u.add_effect( effect_onfire, 8_turns, bp_torso );
1534 u.hurtall( rng( 2, 6 ), nullptr );
1535 }
1536 }
1537 // Both gases are unhealthy and become deadly if you cross a related threshold.
1538 if( ft == fd_fungicidal_gas || ft == fd_insecticidal_gas ) {
1539 // The gas won't harm you inside a vehicle.
1540 if( !inside ) {
1541 // Full body suits protect you from the effects of the gas.
1542 if( !( u.worn_with_flag( flag_GAS_PROOF ) && u.get_env_resist( bodypart_id( "mouth" ) ) >= 15 &&
1543 u.get_env_resist( bodypart_id( "eyes" ) ) >= 15 ) ) {
1544 const int intensity = cur.get_field_intensity();
1545 bool inhaled = u.add_env_effect( effect_poison, bp_mouth, 5, intensity * 1_minutes );
1547 ( ft == fd_insecticidal_gas && ( u.get_highest_category() == "INSECT" ||
1548 u.get_highest_category() == "SPIDER" ) ) ) {
1549 inhaled |= u.add_env_effect( effect_badpoison, bp_mouth, 5, intensity * 1_minutes );
1550 u.hurtall( rng( intensity, intensity * 2 ), nullptr );
1551 u.add_msg_if_player( m_bad, _( "The %s burns your skin." ), cur.name() );
1552 }
1553
1554 if( inhaled ) {
1555 u.add_msg_if_player( m_bad, _( "The %s makes you feel sick." ), cur.name() );
1556 }
1557 }
1558 }
1559 }
1560 }
1561}
std::string body_part_name_accusative(body_part bp, int number)
Returns the matching accusative name of the body_part token, i.e.
Definition: bodypart.cpp:329
@ bp_foot_l
Definition: bodypart.h:50
@ bp_leg_r
Definition: bodypart.h:49
@ bp_eyes
Definition: bodypart.h:42
@ bp_hand_l
Definition: bodypart.h:46
@ bp_arm_l
Definition: bodypart.h:44
@ bp_leg_l
Definition: bodypart.h:48
@ bp_hand_r
Definition: bodypart.h:47
@ bp_head
Definition: bodypart.h:41
@ bp_torso
Definition: bodypart.h:40
@ bp_mouth
Definition: bodypart.h:43
@ bp_foot_r
Definition: bodypart.h:51
@ bp_arm_r
Definition: bodypart.h:45
void mod_pain(int npain) override
Modifies a pain value by player traits before passing it to Creature::mod_pain()
Definition: character.cpp:750
bool is_elec_immune() const override
Returns true is the player is protected from electric shocks.
Definition: character.cpp:6086
bool worn_with_flag(const std::string &flag, const bodypart_id &bp=bodypart_str_id::NULL_ID()) const
Returns true if the player is wearing an item with the given flag.
Definition: character.cpp:3231
bool is_on_ground() const override
Returns true if the player is knocked over or has broken legs.
Definition: character.cpp:883
std::list< item > worn
Definition: character.h:1532
int get_env_resist(bodypart_id bp) const override
Returns overall env_resist on a body_part.
Definition: character.cpp:6987
bool has_two_arms() const
Returns true if the player has two functioning arms.
Definition: character.cpp:1201
int get_armor_cut(bodypart_id bp) const override
Returns overall cutting resistance for the body_part.
Definition: character.cpp:6830
std::string get_highest_category() const
Returns the highest mutation category.
Definition: character.cpp:7797
bool is_wearing(const item &itm) const
Returns true if the player is wearing the item.
Definition: character.cpp:3201
void hurtall(int dam, Creature *source, bool disturb=true)
Hurts all body parts for dam, no armor reduction.
Definition: character.cpp:8617
bool irradiate(float rads, bool bypass=false)
Handles mitigation and application of radiation.
Definition: suffer.cpp:1536
static body_part hp_to_bp(hp_part hpart)
Converts an hp_part to a body_part.
Definition: character.cpp:6443
bool has_active_bionic(const bionic_id &b) const
Returns true if the player has the entered bionic id and it is powered on.
Definition: character.cpp:1805
bodypart_id get_random_body_part(bool main=false) const
Definition: creature.cpp:1626
virtual bool is_underwater() const
Definition: creature.cpp:170
std::vector< bodypart_id > get_all_body_parts(bool only_main=false) const
Returns body parts this creature have.
Definition: creature.cpp:1633
int extra_radiation_min() const
Definition: field.cpp:14
int radiation_hurt_damage_min() const
Definition: field.cpp:24
std::string radiation_hurt_message() const
Definition: field.cpp:34
int extra_radiation_max() const
Definition: field.cpp:19
std::string name() const
Definition: field.h:84
int radiation_hurt_damage_max() const
Definition: field.cpp:29
int get_coverage() const
Returns the relative coverage that this item has when worn.
Definition: item.cpp:5900
bool covers(body_part bp) const
Whether this item (when worn) covers the given body part.
Definition: item.cpp:743
int burn_body_part(player &u, field_entry &cur, body_part bp, int scale)
Definition: map_field.cpp:124
void add_msg_if_player(const std::string &msg) const override
Definition: player.cpp:380
bool is_player() const override
Definition: player.h:93
field_type_id fd_bees
Definition: field_type.cpp:371
static const trait_id trait_M_SKIN3("M_SKIN3")
static const std::string flag_GAS_PROOF("GAS_PROOF")
static const efftype_id effect_fungus("fungus")
static const trait_id trait_ELECTRORECEPTORS("ELECTRORECEPTORS")
static const trait_id trait_THRESH_MARLOSS("THRESH_MARLOSS")
static const trait_id trait_WEB_WALKER("WEB_WALKER")
static const efftype_id effect_badpoison("badpoison")
static const itype_id itype_rm13_armor_on("rm13_armor_on")
static const trait_id trait_M_IMMUNE("M_IMMUNE")
static const trait_id trait_THRESH_MYCUS("THRESH_MYCUS")
static const trait_id trait_ACIDPROOF("ACIDPROOF")
static const trait_id trait_M_SKIN2("M_SKIN2")
static const efftype_id effect_stung("stung")
static const efftype_id effect_poison("poison")
static const efftype_id effect_teargas("teargas")
static const bionic_id bio_heatsink("bio_heatsink")
hp_part
Definition: pldata.h:32
@ num_hp_parts
Definition: pldata.h:39
int type_damage(damage_type dt) const
Definition: damage.cpp:172
#define translate_marker(x)
Marks a string literal to be extracted for translation.
Definition: translations.h:30

References _, Creature::add_effect(), Creature::add_env_effect(), add_msg(), player::add_msg_if_player(), player::add_msg_player_or_npc(), bio_heatsink, body_part_name_accusative(), bp_arm_l, bp_arm_r, bp_eyes, bp_foot_l, bp_foot_r, bp_hand_l, bp_hand_r, bp_head, bp_leg_l, bp_leg_r, bp_mouth, bp_torso, burn_body_part(), Creature::check_dead_state(), convert_bp(), item::covers(), Character::deal_damage(), DT_ELECTRIC, DT_HEAT, effect_badpoison, effect_blind, effect_fungus, effect_onfire, effect_poison, effect_stung, effect_teargas, effect_webbed, field_entry::extra_radiation_max(), field_entry::extra_radiation_min(), fd_acid, fd_acid_vent, fd_bees, fd_dazzling, fd_electricity, fd_fatigue, fd_fire, fd_flame_burst, fd_fungal_haze, fd_fungicidal_gas, fd_incendiary, fd_insecticidal_gas, fd_sap, fd_shock_vent, fd_sludge, fd_tear_gas, fd_web, flag_GAS_PROOF(), Creature::get_all_body_parts(), Character::get_armor_cut(), item::get_coverage(), Character::get_env_resist(), get_field(), field_entry::get_field_intensity(), field_entry::get_field_type(), Character::get_highest_category(), Creature::get_random_body_part(), Character::has_active_bionic(), Character::has_trait(), Character::has_two_arms(), Character::hp_to_bp(), Character::hurtall(), string_id< T >::id(), Character::in_vehicle, Character::irradiate(), Character::is_elec_immune(), field_entry::is_field_alive(), Character::is_on_ground(), player::is_player(), Creature::is_underwater(), Character::is_wearing(), itype_rm13_armor_on, m_bad, m_warning, Character::mod_pain(), Creature::moves, field_entry::name(), num_bp, num_hp_parts, one_in(), Character::pos(), field_entry::radiation_hurt_damage_max(), field_entry::radiation_hurt_damage_min(), field_entry::radiation_hurt_message(), rng(), field_entry::set_field_intensity(), teleport::teleport(), dealt_damage_instance::total_damage(), trait_ACIDPROOF, trait_ELECTRORECEPTORS, trait_M_IMMUNE, trait_M_SKIN2, trait_M_SKIN3, trait_THRESH_MARLOSS, trait_THRESH_MYCUS, trait_WEB_WALKER, translate_marker, dealt_damage_instance::type_damage(), veh_at(), Character::worn, Character::worn_with_flag(), and x_in_y().

Referenced by creature_in_field().

◆ point_within_camp()

bool map::point_within_camp ( const tripoint point_check) const

Definition at line 5626 of file map.cpp.

5627{
5628 // TODO: fix point types
5629 const tripoint_abs_omt omt_check( ms_to_omt_copy( point_check ) );
5630 const point_abs_omt p = omt_check.xy();
5631 for( int x2 = -2; x2 < 2; x2++ ) {
5632 for( int y2 = -2; y2 < 2; y2++ ) {
5633 if( cata::optional<basecamp *> bcp = overmap_buffer.find_camp( p + point( x2, y2 ) ) ) {
5634 return ( *bcp )->camp_omt_pos().z() == point_check.z;
5635 }
5636 }
5637 }
5638 return false;
5639}
constexpr auto xy() const
Definition: coordinates.h:130
cata::optional< basecamp * > find_camp(const point_abs_omt &p)

References overmapbuffer::find_camp(), ms_to_omt_copy(), overmap_buffer, coords::coord_point< Point, Origin, Scale >::xy(), and tripoint::z.

Referenced by npc::worker_downtime().

◆ points_in_radius()

tripoint_range< tripoint > map::points_in_radius ( const tripoint center,
size_t  radius,
size_t  radiusz = 0 
) const

Definition at line 8679 of file map.cpp.

8681{
8682 const tripoint min( std::max<int>( 0, center.x - radius ), std::max<int>( 0, center.y - radius ),
8683 clamp<int>( center.z - radiusz, -OVERMAP_DEPTH, OVERMAP_HEIGHT ) );
8684 const tripoint max( std::min<int>( SEEX * my_MAPSIZE - 1, center.x + radius ),
8685 std::min<int>( SEEX * my_MAPSIZE - 1, center.y + radius ), clamp<int>( center.z + radiusz,
8687 return tripoint_range<tripoint>( min, max );
8688}

References center, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, and SEEX.

Referenced by computer_session::action_blood_anal(), computer_session::action_conveyor(), computer_session::action_data_anal(), computer_session::action_deactivate_shock_vent(), computer_session::action_extract_rad_source(), computer_session::action_geiger(), computer_session::action_irradiator(), computer_session::action_sample(), Character::activate_bionic(), add_splash(), npc::alt_attack(), apply_ammo_effects(), are_requirements_nearby(), npc::assess_danger(), bash_furn_success(), Character::blossoms(), activity_handlers::butcher_finish(), leap_actor::call(), can_do_activity_there(), iexamine::cardreader(), iexamine::cardreader_foodplace(), deploy_tent_actor::check_intact(), choose_adjacent_highlight(), activity_handlers::chop_tree_finish(), climb_difficulty(), collapse_at(), collapse_check(), complete_construction(), consider_butchery(), game::control_vehicle(), displace_water(), enumerate_objects_around_point(), Character::env_surgery_bonus(), ranged::execute_shaped_attack(), ranged::expected_coverage(), computer_session::failure_destroy_blood(), computer_session::failure_destroy_data(), computer_session::failure_manhacks(), computer_session::failure_secubots(), computer_session::failure_shutdown(), find_empty_spot_nearby(), find_furnitures_or_vparts_with_flag_in_radius(), find_furnitures_with_flag_in_radius(), find_potential_computer_point(), hacking_activity_actor::finish(), activity_handlers::forage_finish(), game::forced_door_closing(), basecamp::form_crafting_inventory(), inventory::form_from_map(), generic_multi_activity_check_requirement(), generic_multi_activity_locations(), get_creatures_in_radius(), get_heat_radiation(), liquid_handler::get_liquid_target(), zone_manager::get_point_set_loot(), iexamine::getGasPumpByNumber(), iexamine::getNearFilledGasTank(), getNearPumpCount(), npc::go_to_omt_destination(), handle_action_menu(), has_adjacent_furniture_with(), has_nearby_chair(), has_nearby_fire(), has_nearby_table(), has_neighbor(), is_cornerfloor(), is_wall_adjacent(), map_funcs::migo_nerve_cage_removal(), game::monmove(), npc::move_away_from(), MapExtras::mx_casings(), MapExtras::mx_corpses(), MapExtras::mx_looters(), MapExtras::mx_marloss_pilgrimage(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), MapExtras::mx_portal(), MapExtras::mx_portal_in(), iexamine::nanofab(), iuse::note_bionics(), trap::on_disarmed(), operator_present(), tutorial_game::per_turn(), photo_def_for_camera_point(), character_funcs::pick_safe_adjacent_tile(), place_construction(), game::place_critter_around(), mission_start::place_deposit_box(), game::place_player(), place_vending(), iexamine::portable_structure(), tutorial_game::post_action(), game::process_artifact(), process_fields_in_submap(), relic_funcs::process_recharge_entry(), propagate_suspension_check(), avatar_action::ramp_move(), reachable_flood_steps(), editmap::recalc_target(), requirements_map(), mattack::riotbot(), route_adjacent(), character_funcs::search_surroundings(), mattack::shriek_stun(), spawn_monsters_submap(), mdeath::splatter(), Character::spores(), fungal_effects::spread_fungus(), spread_gas(), monster::stumble(), activity_handlers::travel_do_turn(), explosion_iuse::trigger_explosion(), try_remove_grab(), turnOnSelectedPump(), place_trap_actor::use(), deploy_tent_actor::use(), use_amount(), game::vertical_move(), and npc::worker_downtime().

◆ points_in_rectangle()

tripoint_range< tripoint > map::points_in_rectangle ( const tripoint from,
const tripoint to 
) const

Definition at line 8669 of file map.cpp.

8670{
8671 const tripoint min( std::max( 0, std::min( from.x, to.x ) ), std::max( 0, std::min( from.y,
8672 to.y ) ), std::max( -OVERMAP_DEPTH, std::min( from.z, to.z ) ) );
8673 const tripoint max( std::min( SEEX * my_MAPSIZE - 1, std::max( from.x, to.x ) ),
8674 std::min( SEEX * my_MAPSIZE - 1, std::max( from.y, to.y ) ), std::min( OVERMAP_HEIGHT,
8675 std::max( from.z, to.z ) ) );
8676 return tripoint_range<tripoint>( min, max );
8677}

References my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, SEEX, tripoint::x, tripoint::y, and tripoint::z.

Referenced by apply_camp_ownership(), apply_faction_ownership(), debug_menu::debug(), draw_lab(), draw_mine(), farm_action(), game::find_or_make_stairs(), generate_lightmap(), jmapgen_setmap::has_vehicle_collision(), avatar_action::move(), MapExtras::mx_portal(), om_cutdown_trees(), om_harvest_furn(), om_harvest_itm(), and om_harvest_ter().

◆ points_on_zlevel() [1/2]

◆ points_on_zlevel() [2/2]

tripoint_range< tripoint > map::points_on_zlevel ( int  z) const

Same as above, but uses the specific z-level.

If the given z-level is invalid, it returns an empty range.

Definition at line 8690 of file map.cpp.

8691{
8692 if( z < -OVERMAP_DEPTH || z > OVERMAP_HEIGHT ) {
8693 // TODO: need a default constructor that creates an empty range.
8695 }
8697 tripoint( 0, 0, z ), tripoint( SEEX * my_MAPSIZE - 1, SEEY * my_MAPSIZE - 1, z ) );
8698}

References my_MAPSIZE, OVERMAP_HEIGHT, SEEX, SEEY, tripoint_above, and tripoint_zero.

◆ process_falling()

void map::process_falling ( )

Invoked drop_everything on cached dirty tiles.

Definition at line 2332 of file map.cpp.

2333{
2334 if( !zlevels ) {
2335 support_cache_dirty.clear();
2336 return;
2337 }
2338
2339 if( !support_cache_dirty.empty() ) {
2340 add_msg( m_debug, "Checking %d tiles for falling objects",
2341 support_cache_dirty.size() );
2342 // We want the cache to stay constant, but falling can change it
2343 std::set<tripoint> last_cache = std::move( support_cache_dirty );
2344 support_cache_dirty.clear();
2345 for( const tripoint &p : last_cache ) {
2346 drop_everything( p );
2347 }
2348 }
2349}
void drop_everything(const tripoint &p)
Handles map objects of given type (not creatures) falling down.
Definition: map.cpp:2103
std::set< tripoint > support_cache_dirty
Definition: map.h:1491

References add_msg(), drop_everything(), m_debug, avatar_action::move(), support_cache_dirty, and zlevels.

Referenced by game::do_turn().

◆ process_fields()

void map::process_fields ( )

Definition at line 141 of file map_field.cpp.

142{
143 const int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
144 const int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
145 for( int z = minz; z <= maxz; z++ ) {
146 auto &field_cache = get_cache( z ).field_cache;
147 for( int x = 0; x < my_MAPSIZE; x++ ) {
148 for( int y = 0; y < my_MAPSIZE; y++ ) {
149 if( field_cache[ x + y * MAPSIZE ] ) {
150 submap *const current_submap = get_submap_at_grid( { x, y, z } );
151 process_fields_in_submap( current_submap, tripoint( x, y, z ) );
152 }
153 }
154 }
155
156 // no need to invalidate "transparency" and "seen" caches here
157 // they are invalidated point by point inside the `process_fields_in_submap`
158 }
159}
void process_fields_in_submap(submap *current_submap, const tripoint &submap_pos)
Definition: map_field.cpp:396

References abs_sub, level_cache::field_cache, get_cache(), get_submap_at_grid(), MAPSIZE, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, process_fields_in_submap(), tripoint::z, and zlevels.

Referenced by game::do_turn().

◆ process_fields_in_submap()

void map::process_fields_in_submap ( submap current_submap,
const tripoint submap_pos 
)

Definition at line 396 of file map_field.cpp.

398{
399 scent_block sblk( submap, g->scent );
400
401 // Holds m.field_at(x,y).find_field(fd_some_field) type returns.
402 // Just to avoid typing that long string for a temp value.
403 field_entry *tmpfld = nullptr;
404
405 map &here = get_map();
406 tripoint thep;
407 thep.z = submap.z;
408
409 // Initialize the map tile wrapper
410 maptile map_tile( current_submap, point_zero );
411 int &locx = map_tile.pos_.x;
412 int &locy = map_tile.pos_.y;
413 const point sm_offset( submap.x * SEEX, submap.y * SEEY );
414
415 // Loop through all tiles in this submap indicated by current_submap
416 for( locx = 0; locx < SEEX; locx++ ) {
417 for( locy = 0; locy < SEEY; locy++ ) {
418 // Get a reference to the field variable from the submap;
419 // contains all the pointers to the real field effects.
420 field &curfield = current_submap->get_field( { static_cast<int>( locx ), static_cast<int>( locy ) } );
421
422 // when displayed_field_type == fd_null it means that `curfield` has no fields inside
423 // avoids instantiating (relatively) expensive map iterator
424 if( !curfield.displayed_field_type() ) {
425 continue;
426 }
427
428 // This is a translation from local coordinates to submap coordinates.
429 // All submaps are in one long 1d array.
430 thep.x = locx + sm_offset.x;
431 thep.y = locy + sm_offset.y;
432 // A const reference to the tripoint above, so that the code below doesn't accidentally change it
433 const tripoint &p = thep;
434
435 // This should be true only when the field in the current tile changes transparency state,
436 // More correctly: not just when the field is opaque, but when it changes state
437 // to a more/less transparent one
438 bool dirty_transparency_cache = false;
439
440 for( auto it = curfield.begin(); it != curfield.end(); ) {
441 // Iterating through all field effects in the submap's field.
442 field_entry &cur = it->second;
443
444 // Holds cur.get_field_type() as that is what the old system used before rewrite.
445 field_type_id cur_fd_type_id = cur.get_field_type();
446
447 // The field might have been killed by processing a neighbor field
448 if( !cur.is_field_alive() ) {
449 if( !cur_fd_type_id->get_transparent( cur.get_field_intensity() - 1 ) ) {
450 dirty_transparency_cache = true;
451 }
452 --current_submap->field_count;
453 curfield.remove_field( it++ );
454 continue;
455 }
456
457 // Again, legacy support in the event someone Mods set_field_intensity to allow more values.
458 if( cur.get_field_intensity() > 3 || cur.get_field_intensity() < 1 ) {
459 // TODO: Remove this eventually as we would suppoort more than 3 field intensity levels
460 debugmsg( "Whoooooa intensity of %d", cur.get_field_intensity() );
461 }
462
463 dirty_transparency_cache |= cur_fd_type_id->dirty_transparency_cache;
464
465 // Don't process "newborn" fields. This gives the player time to run if they need to.
466 if( cur.get_field_age() == 0_turns ) {
467 cur_fd_type_id = fd_null;
468 }
469
470 const field_type &cur_fd_type = *cur_fd_type_id;
471
472 // Upgrade field intensity
473 if( cur.intensity_upgrade_chance() > 0 &&
475 cur.intensity_upgrade_duration() > 0_turns &&
478 }
479
480 int part;
481 const ter_t &ter = map_tile.get_ter_t();
482 // Dissipate faster in water
483 if( ter.has_flag( TFLAG_SWIMMABLE ) ) {
485 }
486 if( cur_fd_type_id == fd_acid ) {
487 // Try to fall by a z-level
488 if( zlevels && p.z > -OVERMAP_DEPTH ) {
489 tripoint dst{ p.xy(), p.z - 1 };
490 if( valid_move( p, dst, true, true ) ) {
491 field_entry *acid_there = field_at( dst ).find_field( fd_acid );
492 if( acid_there == nullptr ) {
494 } else {
495 // Math can be a bit off,
496 // but "boiling" falling acid can be allowed to be stronger
497 // than acid that just lies there
498 const int sum_intensity = cur.get_field_intensity() + acid_there->get_field_intensity();
499 const int new_intensity = std::min( 3, sum_intensity );
500 // No way to get precise elapsed time, let's always reset
501 // Allow falling acid to last longer than regular acid to show it off
502 const time_duration new_age = -1_minutes * ( sum_intensity - new_intensity );
503 acid_there->set_field_intensity( new_intensity );
504 acid_there->set_field_age( new_age );
505 }
506
507 // Set ourselves up for removal
508 cur.set_field_intensity( 0 );
509 }
510 }
511 // TODO: Allow spreading to the sides if age < 0 && intensity == 3
512 }
513 if( cur_fd_type.apply_slime_factor > 0 ) {
514 sblk.apply_slime( p, cur.get_field_intensity() * cur_fd_type.apply_slime_factor );
515 }
516 if( cur_fd_type_id == fd_fire ) {
517 cur.set_field_age( std::max( -24_hours, cur.get_field_age() ) );
518 // Entire objects for ter/frn for flags
519 const ter_t &ter = map_tile.get_ter_t();
520 const furn_t &frn = map_tile.get_furn_t();
521
522 // We've got ter/furn cached, so let's use that
523 const bool is_sealed = ter_furn_has_flag( ter, frn, TFLAG_SEALED ) &&
525 // Consumed items count
526 int consumed = 0;
527 // How much time to add to the fire's life due to burned items/terrain/furniture
528 time_duration time_added = 0_turns;
529 // Checks if the fire can spread
530 const bool can_spread = !ter_furn_has_flag( ter, frn, TFLAG_FIRE_CONTAINER );
531 const bool no_floor = ter.has_flag( TFLAG_NO_FLOOR );
532 // If the flames are in furniture with fire_container flag like brazier or oven,
533 // they're fully contained, so skip consuming terrain
534 const bool can_burn = !no_floor && can_spread &&
535 ( check_flammable( ter ) || check_flammable( frn ) );
536 // The huge indent below should probably be somehow moved away from here
537 // without forcing the function to use i_at( p ) for fires without items
538 if( !is_sealed && map_tile.get_item_count() > 0 ) {
539 map_stack items_here = i_at( p );
540 std::vector<item> new_content;
541 for( auto explosive = items_here.begin(); explosive != items_here.end(); ) {
542 if( explosive->will_explode_in_fire() ) {
543 // We need to make a copy because the iterator validity is not predictable
544 item copy = *explosive;
545 explosive = items_here.erase( explosive );
546 if( copy.detonate( p, new_content ) ) {
547 // Need to restart, iterators may not be valid
548 explosive = items_here.begin();
549 }
550 } else {
551 ++explosive;
552 }
553 }
554
555 fire_data frd( cur.get_field_intensity(), !can_spread );
556 // The highest # of items this fire can remove in one turn
557 int max_consume = cur.get_field_intensity() * 2;
558
559 for( auto fuel = items_here.begin(); fuel != items_here.end() && consumed < max_consume; ) {
560 // `item::burn` modifies the charges in order to simulate some of them getting
561 // destroyed by the fire, this changes the item weight, but may not actually
562 // destroy it. We need to spawn products anyway.
563 const units::mass old_weight = fuel->weight( false );
564 bool destroyed = fuel->burn( frd );
565 // If the item is considered destroyed, it may have negative charge count,
566 // see `item::burn?. This in turn means `item::weight` returns a negative value,
567 // which we can not use, so only call `weight` when it's still an existing item.
568 const units::mass new_weight = destroyed ? 0_gram : fuel->weight( false );
569 if( old_weight != new_weight ) {
570 create_burnproducts( p, *fuel, old_weight - new_weight );
571 }
572
573 if( destroyed ) {
574 // If we decided the item was destroyed by fire, remove it.
575 // But remember its contents, except for irremovable mods, if any
576 const std::list<item *> content_list = fuel->contents.all_items_top();
577 for( item *it : content_list ) {
578 if( !it->is_irremovable() ) {
579 new_content.push_back( item( *it ) );
580 }
581 }
582 fuel = items_here.erase( fuel );
583 consumed++;
584 } else {
585 ++fuel;
586 }
587 }
588
589 spawn_items( p, new_content );
590 time_added = 1_turns * roll_remainder( frd.fuel_produced );
591 }
592
593 // Get the part of the vehicle in the fire (_internal skips the boundary check)
594 vehicle *veh = veh_at_internal( p, part );
595 if( veh != nullptr ) {
596 veh->damage( part, cur.get_field_intensity() * 10, DT_HEAT, true );
597 // Damage the vehicle in the fire.
598 }
599 if( can_burn ) {
600 if( ter.has_flag( TFLAG_SWIMMABLE ) ) {
601 // Flames die quickly on water
602 cur.set_field_age( cur.get_field_age() + 4_minutes );
603 }
604
605 // Consume the terrain we're on
606 if( ter_furn_has_flag( ter, frn, TFLAG_FLAMMABLE ) ) {
607 // The fire feeds on the ground itself until max intensity.
608 time_added += 1_turns * ( 5 - cur.get_field_intensity() );
609 if( cur.get_field_intensity() > 1 &&
610 one_in( 200 - cur.get_field_intensity() * 50 ) ) {
611 destroy( p, false );
612 }
613
614 } else if( ter_furn_has_flag( ter, frn, TFLAG_FLAMMABLE_HARD ) &&
615 one_in( 3 ) ) {
616 // The fire feeds on the ground itself until max intensity.
617 time_added += 1_turns * ( 4 - cur.get_field_intensity() );
618 if( cur.get_field_intensity() > 1 &&
619 one_in( 200 - cur.get_field_intensity() * 50 ) ) {
620 destroy( p, false );
621 }
622
623 } else if( ter.has_flag( TFLAG_FLAMMABLE_ASH ) ) {
624 // The fire feeds on the ground itself until max intensity.
625 time_added += 1_turns * ( 5 - cur.get_field_intensity() );
626 if( cur.get_field_intensity() > 1 &&
627 one_in( 200 - cur.get_field_intensity() * 50 ) ) {
628 if( p.z > 0 ) {
629 // We're in the air
630 ter_set( p, t_open_air );
631 } else {
632 ter_set( p, t_dirt );
633 }
634 }
635
636 } else if( frn.has_flag( TFLAG_FLAMMABLE_ASH ) ) {
637 // The fire feeds on the ground itself until max intensity.
638 time_added += 1_turns * ( 5 - cur.get_field_intensity() );
639 if( cur.get_field_intensity() > 1 &&
640 one_in( 200 - cur.get_field_intensity() * 50 ) ) {
641 furn_set( p, f_ash );
642 add_item_or_charges( p, item( "ash" ) );
643 }
644
645 }
646 }
647
648 if( ter.has_flag( TFLAG_NO_FLOOR ) && zlevels && p.z > -OVERMAP_DEPTH ) {
649 // We're hanging in the air - let's fall down
650 tripoint dst{ p.xy(), p.z - 1 };
651 if( valid_move( p, dst, true, true ) ) {
652 maptile dst_tile = maptile_at_internal( dst );
653 field_entry *fire_there = dst_tile.find_field( fd_fire );
654 if( fire_there == nullptr ) {
655 add_field( dst, fd_fire, 1, 0_turns, false );
657 } else {
658 // Don't fuel raging fires or they'll burn forever
659 // as they can produce small fires above themselves
660 int new_intensity = std::max( cur.get_field_intensity(),
661 fire_there->get_field_intensity() );
662 // Allow smaller fires to combine
663 if( new_intensity < 3 &&
664 cur.get_field_intensity() == fire_there->get_field_intensity() ) {
665 new_intensity++;
666 }
667 // A raging fire below us can support us for a while
668 // Otherwise decay and decay fast
669 if( fire_there->get_field_intensity() < 3 || one_in( 10 ) ) {
671 }
672 fire_there->set_field_intensity( new_intensity );
673 }
674 break;
675 }
676 }
677 // Lower age is a longer lasting fire
678 if( time_added != 0_turns ) {
679 cur.set_field_age( cur.get_field_age() - time_added );
680 } else if( can_burn ) {
681 // Nothing to burn = fire should be dying out faster
682 // Drain more power from big fires, so that they stop raging over nothing
683 // Except for fires on stoves and fireplaces, those are made to keep the fire alive
684 cur.mod_field_age( 10_seconds * cur.get_field_intensity() );
685 }
686
687 // Allow raging fires (and only raging fires) to spread up
688 // Spreading down is achieved by wrecking the walls/floor and then falling
689 if( zlevels && cur.get_field_intensity() == 3 && p.z < OVERMAP_HEIGHT ) {
690 const tripoint dst_p = tripoint( p.xy(), p.z + 1 );
691 // Let it burn through the floor
692 maptile dst = maptile_at_internal( dst_p );
693 const auto &dst_ter = dst.get_ter_t();
694 if( dst_ter.has_flag( TFLAG_NO_FLOOR ) ||
695 dst_ter.has_flag( TFLAG_FLAMMABLE ) ||
696 dst_ter.has_flag( TFLAG_FLAMMABLE_ASH ) ||
697 dst_ter.has_flag( TFLAG_FLAMMABLE_HARD ) ) {
698 field_entry *nearfire = dst.find_field( fd_fire );
699 if( nearfire != nullptr ) {
700 nearfire->mod_field_age( -2_turns );
701 } else {
702 add_field( dst_p, fd_fire, 1, 0_turns, false );
703 }
704 // Fueling fires above doesn't cost fuel
705 }
706 }
707
708 // Below we will access our nearest 8 neighbors, so let's cache them now
709 // This should probably be done more globally, because large fires will re-do it a lot
710 auto neighs = get_neighbors( p );
711
712 // If the flames are in a pit, it can't spread to non-pit
713 const bool in_pit = can_spread && ter.id.id() == t_pit;
714
715 // Count adjacent fires, to optimize out needless smoke and hot air
716 int adjacent_fires = 0;
717
718 // If the flames are big, they contribute to adjacent flames
719 if( can_spread ) {
720 if( cur.get_field_intensity() > 1 && one_in( 3 ) ) {
721 // Basically: Scan around for a spot,
722 // if there is more fire there, make it bigger and give it some fuel.
723 // This is how big fires spend their excess age:
724 // making other fires bigger. Flashpoint.
725 size_t end_it = static_cast<size_t>( rng( 0, neighs.size() - 1 ) );
726 for( size_t i = ( end_it + 1 ) % neighs.size(), count = 0;
727 count != neighs.size() && cur.get_field_age() < 0_turns;
728 i = ( i + 1 ) % neighs.size(), count++ ) {
729 maptile &dst = neighs[i].second;
730 auto dstfld = dst.find_field( fd_fire );
731 // If the fire exists and is weaker than ours, boost it
732 if( dstfld != nullptr &&
733 ( dstfld->get_field_intensity() <= cur.get_field_intensity() ||
734 dstfld->get_field_age() > cur.get_field_age() ) &&
735 ( in_pit == ( dst.get_ter() == t_pit ) ) ) {
736 if( dstfld->get_field_intensity() < 2 ) {
737 dstfld->set_field_intensity( dstfld->get_field_intensity() + 1 );
738 }
739
740 dstfld->set_field_age( dstfld->get_field_age() - 5_minutes );
741 cur.set_field_age( cur.get_field_age() + 5_minutes );
742 }
743 if( dstfld != nullptr ) {
744 adjacent_fires++;
745 }
746 }
747 } else if( cur.get_field_age() < 0_turns && cur.get_field_intensity() < 3 ) {
748 // See if we can grow into a stage 2/3 fire, for this
749 // burning neighbors are necessary in addition to
750 // field age < 0, or alternatively, a LOT of fuel.
751
752 // The maximum fire intensity is 1 for a lone fire, 2 for at least 1 neighbor,
753 // 3 for at least 2 neighbors.
754 int maximum_intensity = 1;
755
756 // The following logic looks a bit complex due to optimization concerns, so here are the semantics:
757 // 1. Calculate maximum field intensity based on fuel, -50 minutes is 2(medium), -500 minutes is 3(raging)
758 // 2. Calculate maximum field intensity based on neighbors, 3 neighbors is 2(medium), 7 or more neighbors is 3(raging)
759 // 3. Pick the higher maximum between 1. and 2.
760 if( cur.get_field_age() < -500_minutes ) {
761 maximum_intensity = 3;
762 } else {
763 for( auto &neigh : neighs ) {
764 if( neigh.second.get_field().find_field( fd_fire ) != nullptr ) {
765 adjacent_fires++;
766 }
767 }
768 maximum_intensity = 1 + ( adjacent_fires >= 3 ) + ( adjacent_fires >= 7 );
769
770 if( maximum_intensity < 2 && cur.get_field_age() < -50_minutes ) {
771 maximum_intensity = 2;
772 }
773 }
774
775 // If we consumed a lot, the flames grow higher
776 if( cur.get_field_intensity() < maximum_intensity && cur.get_field_age() < 0_turns ) {
777 // Fires under 0 age grow in size. Level 3 fires under 0 spread later on.
778 // Weaken the newly-grown fire
780 cur.set_field_age( cur.get_field_age() + 10_minutes * cur.get_field_intensity() );
781 }
782 }
783
784 // Consume adjacent fuel / terrain / webs to spread.
785 // Our iterator will start at end_i + 1 and increment from there and then wrap around.
786 // This guarantees it will check all neighbors, starting from a random one
787 const size_t end_i = static_cast<size_t>( rng( 0, neighs.size() - 1 ) );
788 for( size_t i = ( end_i + 1 ) % neighs.size(), count = 0;
789 count != neighs.size();
790 i = ( i + 1 ) % neighs.size(), count++ ) {
791 if( one_in( cur.get_field_intensity() * 2 ) ) {
792 // Skip some processing to save on CPU
793 continue;
794 }
795
796 tripoint &dst_p = neighs[i].first;
797 maptile &dst = neighs[i].second;
798 // No bounds checking here: we'll treat the invalid neighbors as valid.
799 // We're using the map tile wrapper, so we can treat invalid tiles as sentinels.
800 // This will create small oddities on map edges, but nothing more noticeable than
801 // "cut-off" that happens with bounds checks.
802
803 field_entry *nearfire = dst.find_field( fd_fire );
804 if( nearfire != nullptr ) {
805 // We handled supporting fires in the section above, no need to do it here
806 continue;
807 }
808
809 field_entry *nearwebfld = dst.find_field( fd_web );
810 int spread_chance = 25 * ( cur.get_field_intensity() - 1 );
811 if( nearwebfld != nullptr ) {
812 spread_chance = 50 + spread_chance / 2;
813 }
814
815 const ter_t &dster = dst.get_ter_t();
816 const furn_t &dsfrn = dst.get_furn_t();
817 // Allow weaker fires to spread occasionally
818 const int power = cur.get_field_intensity() + one_in( 5 );
819 if( can_spread && rng( 1, 100 ) < spread_chance &&
820 ( check_flammable( dster ) || check_flammable( dsfrn ) ) &&
821 ( in_pit == ( dster.id.id() == t_pit ) ) &&
822 (
823 ( power >= 3 && cur.get_field_age() < 0_turns && one_in( 20 ) ) ||
824 ( power >= 2 && ( ter_furn_has_flag( dster, dsfrn, TFLAG_FLAMMABLE ) && one_in( 2 ) ) ) ||
825 ( power >= 2 && ( ter_furn_has_flag( dster, dsfrn, TFLAG_FLAMMABLE_ASH ) && one_in( 2 ) ) ) ||
826 ( power >= 3 && ( ter_furn_has_flag( dster, dsfrn, TFLAG_FLAMMABLE_HARD ) && one_in( 5 ) ) ) ||
827 nearwebfld || ( dst.get_item_count() > 0 &&
829 one_in( 5 ) )
830 ) ) {
831 // Nearby open flammable ground? Set it on fire.
832 add_field( dst_p, fd_fire, 1, 0_turns, false );
833 tmpfld = dst.find_field( fd_fire );
834 if( tmpfld != nullptr ) {
835 // Make the new fire quite weak, so that it doesn't start jumping around instantly
836 tmpfld->set_field_age( 2_minutes );
837 // Consume a bit of our fuel
838 cur.set_field_age( cur.get_field_age() + 1_minutes );
839 }
840 if( nearwebfld ) {
841 nearwebfld->set_field_intensity( 0 );
842 }
843 }
844 }
845 }
846 }
847
848 // Spread gaseous fields
849 if( cur.gas_can_spread() ) {
850 const int gas_percent_spread = cur_fd_type.percent_spread;
851 if( gas_percent_spread > 0 ) {
852 const time_duration outdoor_age_speedup = cur_fd_type.outdoor_age_speedup;
853 spread_gas( cur, p, gas_percent_spread, outdoor_age_speedup, sblk );
854 }
855 }
856
857 if( cur_fd_type_id == fd_fungal_haze ) {
858 if( one_in( 10 - 2 * cur.get_field_intensity() ) ) {
859 // Haze'd terrain
860 fungal_effects( *g, here ).spread_fungus( p );
861 }
862 }
863
864 // Process npc complaints
865 const std::tuple<int, std::string, time_duration, std::string> &npc_complain_data =
866 cur_fd_type.npc_complain_data;
867 const int chance = std::get<0>( npc_complain_data );
868 if( chance > 0 && one_in( chance ) ) {
869 if( npc *const np = g->critter_at<npc>( p, false ) ) {
870 np->complain_about( std::get<1>( npc_complain_data ),
871 std::get<2>( npc_complain_data ),
872 std::get<3>( npc_complain_data ) );
873 }
874 }
875
876 // Apply radiation
877 if( cur.extra_radiation_max() > 0 ) {
878 int extra_radiation = rng( cur.extra_radiation_min(), cur.extra_radiation_max() );
879 adjust_radiation( p, extra_radiation );
880 }
881
882 // Apply wandering fields from vents
883 if( cur_fd_type.wandering_field ) {
884 for( const tripoint &pnt : points_in_radius( p, cur.get_field_intensity() - 1 ) ) {
885 field &wandering_field = get_field( pnt );
886 tmpfld = wandering_field.find_field( cur_fd_type.wandering_field );
887 if( tmpfld && tmpfld->get_field_intensity() < cur.get_field_intensity() ) {
888 tmpfld->set_field_intensity( tmpfld->get_field_intensity() + 1 );
889 } else {
890 add_field( pnt, cur_fd_type.wandering_field, cur.get_field_intensity() );
891 }
892 }
893 }
894
895 if( cur_fd_type_id == fd_fire_vent ) {
896
897 if( cur.get_field_intensity() > 1 ) {
898 if( one_in( 3 ) ) {
900 }
902 } else {
903 dirty_transparency_cache = true;
904 add_field( p, fd_flame_burst, 3, cur.get_field_age() );
905 cur.set_field_intensity( 0 );
906 }
907 }
908 if( cur_fd_type_id == fd_flame_burst ) {
909 if( cur.get_field_intensity() > 1 ) {
912 } else {
913 dirty_transparency_cache = true;
914 add_field( p, fd_fire_vent, 3, cur.get_field_age() );
915 cur.set_field_intensity( 0 );
916 }
917 }
918 if( cur_fd_type_id == fd_electricity ) {
919 // 4 in 5 chance to spread
920 if( !one_in( 5 ) ) {
921 std::vector<tripoint> valid;
922 // We're grounded
923 if( impassable( p ) && cur.get_field_intensity() > 1 ) {
924 int tries = 0;
925 tripoint pnt;
926 pnt.z = p.z;
927 while( tries < 10 && cur.get_field_age() < 5_minutes && cur.get_field_intensity() > 1 ) {
928 pnt.x = p.x + rng( -1, 1 );
929 pnt.y = p.y + rng( -1, 1 );
930 if( passable( pnt ) && !obstructed_by_vehicle_rotation( p, pnt ) ) {
931 add_field( pnt, fd_electricity, 1, cur.get_field_age() + 1_turns );
933 tries = 0;
934 } else {
935 tries++;
936 }
937 }
938 // We're not grounded; attempt to ground
939 } else {
940 for( const tripoint &dst : points_in_radius( p, 1 ) ) {
941 // Grounded tiles first
942 if( impassable( dst ) ) {
943 valid.push_back( dst );
944 }
945 }
946 // Spread to adjacent space, then
947 if( valid.empty() ) {
948 tripoint dst( p + point( rng( -1, 1 ), rng( -1, 1 ) ) );
949 field_entry *elec = get_field( dst ).find_field( fd_electricity );
950 bool pass = passable( dst ) && !obstructed_by_vehicle_rotation( p, dst );
951 if( pass && elec != nullptr &&
952 elec->get_field_intensity() < 3 ) {
953 elec->set_field_intensity( elec->get_field_intensity() + 1 );
955 } else if( pass ) {
956 add_field( dst, fd_electricity, 1, cur.get_field_age() + 1_turns );
957 }
959 }
960 while( !valid.empty() && cur.get_field_intensity() > 1 ) {
961 const tripoint target = random_entry_removed( valid );
962 add_field( target, fd_electricity, 1, cur.get_field_age() + 1_turns );
964 }
965 }
966 }
967 }
968
969 int monster_spawn_chance = cur.monster_spawn_chance();
970 int monster_spawn_count = cur.monster_spawn_count();
971 if( monster_spawn_count > 0 && monster_spawn_chance > 0 && one_in( monster_spawn_chance ) ) {
972 for( ; monster_spawn_count > 0; monster_spawn_count-- ) {
974 cur.monster_spawn_group(), &monster_spawn_count );
975 if( !spawn_details.name ) {
976 continue;
977 }
980 [this]( const tripoint & n ) {
981 return passable( n );
982 } ) ) {
983 add_spawn( spawn_details.name, spawn_details.pack_size, *spawn_point );
984 }
985 }
986 }
987
988 if( cur_fd_type_id == fd_push_items ) {
989 map_stack items = i_at( p );
990 for( auto pushee = items.begin(); pushee != items.end(); ) {
991 if( pushee->typeId() != itype_rock ||
992 pushee->age() < 1_turns ) {
993 pushee++;
994 } else {
995 item tmp = *pushee;
996 tmp.set_age( 0_turns );
997 pushee = items.erase( pushee );
998 std::vector<tripoint> valid;
999 for( const tripoint &dst : points_in_radius( p, 1 ) ) {
1000 if( get_field( dst, fd_push_items ) != nullptr ) {
1001 valid.push_back( dst );
1002 }
1003 }
1004 if( !valid.empty() ) {
1005 tripoint newp = random_entry( valid );
1006 add_item_or_charges( newp, tmp );
1007 if( g->u.pos() == newp ) {
1008 add_msg( m_bad, _( "A %s hits you!" ), tmp.tname() );
1009 const bodypart_id hit = g->u.get_random_body_part();
1010 g->u.deal_damage( nullptr, hit, damage_instance( DT_BASH, 6 ) );
1011 g->u.check_dead_state();
1012 }
1013
1014 if( npc *const p = g->critter_at<npc>( newp ) ) {
1015 // TODO: combine with player character code above
1016 const bodypart_id hit = g->u.get_random_body_part();
1017 p->deal_damage( nullptr, hit, damage_instance( DT_BASH, 6 ) );
1018 if( g->u.sees( newp ) ) {
1019 add_msg( _( "A %1$s hits %2$s!" ), tmp.tname(), p->name );
1020 }
1021 p->check_dead_state();
1022 } else if( monster *const mon = g->critter_at<monster>( newp ) ) {
1023 mon->apply_damage( nullptr, bodypart_id( "torso" ),
1024 6 - mon->get_armor_bash( bodypart_id( "torso" ) ) );
1025 if( g->u.sees( newp ) ) {
1026 add_msg( _( "A %1$s hits the %2$s!" ), tmp.tname(), mon->name() );
1027 }
1028 mon->check_dead_state();
1029 }
1030 }
1031 }
1032 }
1033 }
1034 if( cur_fd_type_id == fd_shock_vent ) {
1035 if( cur.get_field_intensity() > 1 ) {
1036 if( one_in( 5 ) ) {
1038 }
1039 } else {
1040 cur.set_field_intensity( 3 );
1041 int num_bolts = rng( 3, 6 );
1042 for( int i = 0; i < num_bolts; i++ ) {
1043 int xdir = 0;
1044 int ydir = 0;
1045 while( xdir == 0 && ydir == 0 ) {
1046 xdir = rng( -1, 1 );
1047 ydir = rng( -1, 1 );
1048 }
1049 int dist = rng( 4, 12 );
1050 int boltx = p.x;
1051 int bolty = p.y;
1052 for( int n = 0; n < dist; n++ ) {
1053 boltx += xdir;
1054 bolty += ydir;
1055 add_field( tripoint( boltx, bolty, p.z ), fd_electricity, rng( 2, 3 ) );
1056 if( one_in( 4 ) ) {
1057 if( xdir == 0 ) {
1058 xdir = rng( 0, 1 ) * 2 - 1;
1059 } else {
1060 xdir = 0;
1061 }
1062 }
1063 if( one_in( 4 ) ) {
1064 if( ydir == 0 ) {
1065 ydir = rng( 0, 1 ) * 2 - 1;
1066 } else {
1067 ydir = 0;
1068 }
1069 }
1070 }
1071 }
1072 }
1073 }
1074 if( cur_fd_type_id == fd_acid_vent ) {
1075
1076 if( cur.get_field_intensity() > 1 ) {
1077 if( cur.get_field_age() >= 1_minutes ) {
1079 cur.set_field_age( 0_turns );
1080 }
1081 } else {
1082 cur.set_field_intensity( 3 );
1083 for( const tripoint &t : points_in_radius( p, 5 ) ) {
1084 const field_entry *acid = get_field( t, fd_acid );
1085 if( acid != nullptr && acid->get_field_intensity() == 0 ) {
1086 int new_intensity = 3 - rl_dist( p, t ) / 2 + ( one_in( 3 ) ? 1 : 0 );
1087 if( new_intensity > 3 ) {
1088 new_intensity = 3;
1089 }
1090 if( new_intensity > 0 ) {
1091 add_field( t, fd_acid, new_intensity );
1092 }
1093 }
1094 }
1095 }
1096 }
1097 if( cur_fd_type_id == fd_bees ) {
1098 // Poor bees are vulnerable to so many other fields.
1099 // TODO: maybe adjust effects based on different fields.
1100 if( curfield.find_field( fd_web ) ||
1101 curfield.find_field( fd_fire ) ||
1102 curfield.find_field( fd_smoke ) ||
1103 curfield.find_field( fd_toxic_gas ) ||
1104 curfield.find_field( fd_tear_gas ) ||
1105 curfield.find_field( fd_relax_gas ) ||
1106 curfield.find_field( fd_nuke_gas ) ||
1107 curfield.find_field( fd_gas_vent ) ||
1108 curfield.find_field( fd_smoke_vent ) ||
1109 curfield.find_field( fd_fungicidal_gas ) ||
1110 curfield.find_field( fd_insecticidal_gas ) ||
1111 curfield.find_field( fd_fire_vent ) ||
1112 curfield.find_field( fd_flame_burst ) ||
1113 curfield.find_field( fd_electricity ) ||
1114 curfield.find_field( fd_fatigue ) ||
1115 curfield.find_field( fd_shock_vent ) ||
1116 curfield.find_field( fd_plasma ) ||
1117 curfield.find_field( fd_laser ) ||
1118 curfield.find_field( fd_dazzling ) ||
1119 curfield.find_field( fd_electricity ) ||
1120 curfield.find_field( fd_incendiary ) ) {
1121 // Kill them at the end of processing.
1122 cur.set_field_intensity( 0 );
1123 } else {
1124 // Bees chase the player if in range, wander randomly otherwise.
1125 if( !g->u.is_underwater() &&
1126 rl_dist( p, g->u.pos() ) < 10 &&
1127 clear_path( p, g->u.pos(), 10, 1, 100 ) ) {
1128
1129 std::vector<point> candidate_positions =
1130 squares_in_direction( p.xy(), point( g->u.posx(), g->u.posy() ) );
1131 for( point candidate_position : candidate_positions ) {
1132 field &target_field = get_field( tripoint( candidate_position, p.z ) );
1133 // Only shift if there are no bees already there.
1134 // TODO: Figure out a way to merge bee fields without allowing
1135 // Them to effectively move several times in a turn depending
1136 // on iteration direction.
1137 if( !target_field.find_field( fd_bees ) ) {
1138 add_field( tripoint( candidate_position, p.z ), fd_bees,
1139 cur.get_field_intensity(), cur.get_field_age() );
1140 cur.set_field_intensity( 0 );
1141 break;
1142 }
1143 }
1144 } else {
1145 spread_gas( cur, p, 5, 0_turns, sblk );
1146 }
1147 }
1148 }
1149 if( cur_fd_type_id == fd_incendiary ) {
1150 // Needed for variable scope
1151 tripoint dst( p + point( rng( -1, 1 ), rng( -1, 1 ) ) );
1152 if( has_flag( TFLAG_FLAMMABLE, dst ) ||
1153 has_flag( TFLAG_FLAMMABLE_ASH, dst ) ||
1154 has_flag( TFLAG_FLAMMABLE_HARD, dst ) ) {
1155 add_field( dst, fd_fire, 1 );
1156 }
1157
1158 // Check piles for flammable items and set those on fire
1159 if( flammable_items_at( dst ) ) {
1160 add_field( dst, fd_fire, 1 );
1161 }
1162
1164 }
1165 if( cur_fd_type_id == fd_fungicidal_gas ) {
1166 // Check the terrain and replace it accordingly to simulate the fungus dieing off
1167 const ter_t &ter = map_tile.get_ter_t();
1168 const furn_t &frn = map_tile.get_furn_t();
1169 const int intensity = cur.get_field_intensity();
1170 if( ter.has_flag( flag_FUNGUS ) && one_in( 10 / intensity ) ) {
1171 ter_set( p, t_dirt );
1172 }
1173 if( frn.has_flag( flag_FUNGUS ) && one_in( 10 / intensity ) ) {
1174 furn_set( p, f_null );
1175 }
1176 }
1177
1178 cur.set_field_age( cur.get_field_age() + 1_turns );
1179 auto &fdata = cur.get_field_type().obj();
1180 if( fdata.half_life > 0_turns && cur.get_field_age() > 0_turns &&
1181 dice( 2, to_turns<int>( cur.get_field_age() ) ) > to_turns<int>( fdata.half_life ) ) {
1182 cur.set_field_age( 0_turns );
1184 }
1185 if( !cur.is_field_alive() ) {
1186 --current_submap->field_count;
1187 curfield.remove_field( it++ );
1188 } else {
1189 ++it;
1190 }
1191 }
1192
1193 if( dirty_transparency_cache ) {
1195 set_seen_cache_dirty( thep );
1196 }
1197 }
1198 }
1199 const int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
1200 const int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
1201 for( int z = std::max( submap.z - 1, minz ); z <= std::min( submap.z + 1, maxz ); ++z ) {
1202 auto &field_cache = get_cache( z ).field_cache;
1203 for( int y = std::max( submap.y - 1, 0 ); y <= std::min( submap.y + 1, MAPSIZE - 1 ); ++y ) {
1204 for( int x = std::max( submap.x - 1, 0 ); x <= std::min( submap.x + 1, MAPSIZE - 1 ); ++x ) {
1205 if( get_submap_at_grid( { x, y, z } )->field_count > 0 ) {
1206 field_cache.set( x + y * MAPSIZE );
1207 } else {
1208 field_cache.reset( x + y * MAPSIZE );
1209 }
1210 }
1211 }
1212 }
1213 sblk.commit_modifications();
1214}
bool gas_can_spread()
Definition: field.h:93
time_duration intensity_upgrade_duration() const
Definition: field.cpp:44
mongroup_id monster_spawn_group() const
Definition: field.cpp:64
time_duration get_underwater_age_speedup() const
Definition: field.h:97
int monster_spawn_count() const
Definition: field.cpp:54
time_duration mod_field_age(const time_duration &mod_age)
Adds given value to age.
Definition: field.h:73
int intensity_upgrade_chance() const
Definition: field.cpp:39
int monster_spawn_radius() const
Definition: field.cpp:59
int monster_spawn_chance() const
Definition: field.cpp:49
std::map< field_type_id, field_entry >::iterator begin()
Definition: field.cpp:251
std::map< field_type_id, field_entry >::iterator end()
Definition: field.cpp:261
void spread_fungus(const tripoint &p)
std::string tname(unsigned int quantity=1, bool with_prefix=true, unsigned int truncate=0) const
Return the (translated) item name.
Definition: item.cpp:4554
void set_age(const time_duration &age)
Definition: item.cpp:10005
bool detonate(const tripoint &p, std::vector< item > &drops)
Detonates the item and adds remains (if any) to drops.
Definition: item.cpp:8749
std::array< std::pair< tripoint, maptile >, 8 > get_neighbors(const tripoint &p)
Definition: map_field.cpp:190
void create_hot_air(const tripoint &p, int intensity)
Definition: map_field.cpp:363
bool clear_path(const tripoint &f, const tripoint &t, int range, int cost_min, int cost_max) const
Check whether there's a direct line of sight between F and T with the additional movecost restraints.
Definition: map.cpp:6468
void spread_gas(field_entry &cur, const tripoint &p, int percent_spread, const time_duration &outdoor_age_speedup, scent_block &sblk)
Definition: map_field.cpp:251
void create_burnproducts(const tripoint &p, const item &fuel, const units::mass &burned_mass)
Definition: map_field.cpp:96
field_type_id fd_laser
Definition: field_type.cpp:359
field_type_id fd_plasma
Definition: field_type.cpp:358
field_type_id fd_null
Definition: field_type.cpp:335
std::vector< point > squares_in_direction(point p1, point p2)
Definition: line.cpp:588
static const itype_id itype_rock("rock")
static bool check_flammable(const map_data_common_t &t)
Definition: map_field.cpp:354
static const std::string flag_FUNGUS("FUNGUS")
furn_id f_ash
Definition: mapdata.cpp:1099
ter_id t_pit
Definition: mapdata.cpp:627
@ TFLAG_FLAMMABLE_HARD
Definition: mapdata.h:294
@ TFLAG_FLAMMABLE
Definition: mapdata.h:277
@ TFLAG_FLAMMABLE_ASH
Definition: mapdata.h:289
@ TFLAG_FIRE_CONTAINER
Definition: mapdata.h:293
bool acid(monster *z)
Definition: monattack.cpp:587
bool get_transparent(int level=0) const
Definition: field_type.h:204
int percent_spread
Definition: field_type.h:157
field_type_id wandering_field
Definition: field_type.h:182
std::tuple< int, std::string, time_duration, std::string > npc_complain_data
Definition: field_type.h:170
time_duration outdoor_age_speedup
Definition: field_type.h:155
int apply_slime_factor
Definition: field_type.h:158
Contains the state of a fire in one tile on one turn.
Definition: fire.h:18
size_t get_item_count() const
Definition: submap.h:304
ter_id get_ter() const
Definition: submap.h:260

References _, abs_sub, mattack::acid(), add_field(), add_item_or_charges(), add_msg(), add_spawn(), adjust_radiation(), scent_block::apply_slime(), field_type::apply_slime_factor, field::begin(), item_stack::begin(), check_flammable(), clear_path(), scent_block::commit_modifications(), detail::count(), create_burnproducts(), create_hot_air(), vehicle::damage(), debugmsg, destroy(), destroyed, item::detonate(), dice(), field_type::dirty_transparency_cache, field::displayed_field_type(), DT_BASH, DT_HEAT, eight_horizontal_neighbors, field::end(), item_stack::end(), map_stack::erase(), explosive, field_entry::extra_radiation_max(), field_entry::extra_radiation_min(), f_ash, f_null, fd_acid, fd_acid_vent, fd_bees, fd_dazzling, fd_electricity, fd_fatigue, fd_fire, fd_fire_vent, fd_flame_burst, fd_fungal_haze, fd_fungicidal_gas, fd_gas_vent, fd_incendiary, fd_insecticidal_gas, fd_laser, fd_nuke_gas, fd_null, fd_plasma, fd_push_items, fd_relax_gas, fd_shock_vent, fd_smoke, fd_smoke_vent, fd_tear_gas, fd_toxic_gas, fd_web, field_at(), level_cache::field_cache, submap::field_count, maptile::find_field(), field::find_field(), flag_FUNGUS(), flammable_items_at(), fire_data::fuel_produced, furn_set(), g, field_entry::gas_can_spread(), get_cache(), get_field(), submap::get_field(), field_entry::get_field_age(), field_entry::get_field_intensity(), field_entry::get_field_type(), maptile::get_furn_t(), maptile::get_item_count(), get_map(), get_neighbors(), get_submap_at_grid(), maptile::get_ter(), maptile::get_ter_t(), field_type::get_transparent(), field_entry::get_underwater_age_speedup(), MonsterGroupManager::GetResultFromGroup(), map_data_common_t::has_flag(), has_flag(), i_at(), int_id< T >::id(), ter_t::id, string_id< T >::id(), impassable(), field_entry::intensity_upgrade_chance(), field_entry::intensity_upgrade_duration(), field_entry::is_field_alive(), itype_rock, m_bad, MAPSIZE, maptile_at_internal(), field_entry::mod_field_age(), field_entry::monster_spawn_chance(), field_entry::monster_spawn_count(), field_entry::monster_spawn_group(), field_entry::monster_spawn_radius(), MonsterGroupResult::name, field_type::npc_complain_data, int_id< T >::obj(), obstructed_by_vehicle_rotation(), calendar::once_every(), one_in(), field_type::outdoor_age_speedup, OVERMAP_DEPTH, OVERMAP_HEIGHT, MonsterGroupResult::pack_size, passable(), field_type::percent_spread, point_zero, points_in_radius(), maptile::pos_, random_entry(), random_entry_removed(), random_point(), field::remove_field(), rl_dist(), rng(), roll_remainder(), SEEX, SEEY, item::set_age(), field_entry::set_field_age(), field_entry::set_field_intensity(), set_seen_cache_dirty(), set_transparency_cache_dirty(), spawn_items(), fungal_effects::spread_fungus(), spread_gas(), squares_in_direction(), t_dirt, t_open_air, t_pit, ter(), ter_furn_has_flag(), ter_set(), TFLAG_ALLOW_FIELD_EFFECT, TFLAG_FIRE_CONTAINER, TFLAG_FLAMMABLE, TFLAG_FLAMMABLE_ASH, TFLAG_FLAMMABLE_HARD, TFLAG_NO_FLOOR, TFLAG_SEALED, TFLAG_SWIMMABLE, item::tname(), valid_move(), veh_at_internal(), field_type::wandering_field, point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, tripoint::z, and zlevels.

Referenced by process_fields().

◆ process_items()

void map::process_items ( )

Definition at line 4639 of file map.cpp.

4640{
4641 const int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
4642 const int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
4643 for( int gz = minz; gz <= maxz; ++gz ) {
4644 level_cache &cache = access_cache( gz );
4645 std::set<tripoint> submaps_with_vehicles;
4646 for( vehicle *this_vehicle : cache.vehicle_list ) {
4647 tripoint pos = this_vehicle->global_pos3();
4648 submaps_with_vehicles.emplace( pos.x / SEEX, pos.y / SEEY, pos.z );
4649 }
4650 for( const tripoint &pos : submaps_with_vehicles ) {
4651 submap *const current_submap = get_submap_at_grid( pos );
4652 // Vehicles first in case they get blown up and drop active items on the map.
4653 process_items_in_vehicles( *current_submap );
4654 }
4655 }
4656 // Making a copy, in case the original variable gets modified during `process_items_in_submap`
4657 const std::set<tripoint> submaps_with_active_items_copy = submaps_with_active_items;
4658 for( const tripoint &abs_pos : submaps_with_active_items_copy ) {
4659 const tripoint local_pos = abs_pos - abs_sub.xy();
4660 submap *const current_submap = get_submap_at_grid( local_pos );
4661 if( !current_submap->active_items.empty() ) {
4662 process_items_in_submap( *current_submap, local_pos );
4663 }
4664 }
4665}
void process_items_in_vehicles(submap &current_submap)
Definition: map.cpp:4702
void process_items_in_submap(submap &current_submap, const tripoint &gridp)
Definition: map.cpp:4682

References abs_sub, access_cache(), submap::active_items, active_item_cache::empty(), get_submap_at_grid(), vehicle::global_pos3(), OVERMAP_DEPTH, OVERMAP_HEIGHT, wrapped_vehicle::pos, process_items_in_submap(), process_items_in_vehicles(), SEEX, SEEY, submaps_with_active_items, level_cache::vehicle_list, tripoint::x, tripoint::xy(), tripoint::y, tripoint::z, and zlevels.

Referenced by game::do_turn().

◆ process_items_in_submap()

void map::process_items_in_submap ( submap current_submap,
const tripoint gridp 
)
private

Definition at line 4682 of file map.cpp.

4683{
4684 // Get a COPY of the active item list for this submap.
4685 // If more are added as a side effect of processing, they are ignored this turn.
4686 // If they are destroyed before processing, they don't get processed.
4687 std::vector<item_reference> active_items = current_submap.active_items.get_for_processing();
4688 const point grid_offset( gridp.x * SEEX, gridp.y * SEEY );
4689 for( item_reference &active_item_ref : active_items ) {
4690 if( !active_item_ref.item_ref ) {
4691 // The item was destroyed, so skip it.
4692 continue;
4693 }
4694
4695 const tripoint map_location = tripoint( grid_offset + active_item_ref.location, gridp.z );
4696 temperature_flag flag = temperature_flag_at_point( *this, map_location );
4697 map_stack items = i_at( map_location );
4698 process_map_items( items, active_item_ref.item_ref, map_location, flag );
4699 }
4700}
std::vector< item_reference > get_for_processing()
Returns the first size() / processing_speed() elements of each list, rounded up.
static bool process_map_items(item_stack &items, safe_reference< item > &item_ref, const tripoint &location, const temperature_flag flag)
Definition: map.cpp:4525

References submap::active_items, active_item_cache::get_for_processing(), i_at(), process_map_items(), SEEX, SEEY, temperature_flag_at_point(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by process_items().

◆ process_items_in_vehicle()

void map::process_items_in_vehicle ( vehicle cur_veh,
submap current_submap 
)
private

Definition at line 4723 of file map.cpp.

4724{
4725 const bool engine_heater_is_on = cur_veh.has_part( "E_HEATER", true ) && cur_veh.engine_on;
4726 for( const vpart_reference &vp : cur_veh.get_any_parts( VPFLAG_FLUIDTANK ) ) {
4727 vp.part().process_contents( vp.pos(), engine_heater_is_on );
4728 }
4729
4730 auto cargo_parts = cur_veh.get_parts_including_carried( VPFLAG_CARGO );
4731 for( const vpart_reference &vp : cargo_parts ) {
4732 process_vehicle_items( cur_veh, vp.part_index() );
4733 }
4734
4735 for( item_reference &active_item_ref : cur_veh.active_items.get_for_processing() ) {
4736 if( empty( cargo_parts ) ) {
4737 return;
4738 } else if( !active_item_ref.item_ref ) {
4739 // The item was destroyed, so skip it.
4740 continue;
4741 }
4742 const auto it = std::find_if( begin( cargo_parts ),
4743 end( cargo_parts ), [&]( const vpart_reference & part ) {
4744 return active_item_ref.location == part.mount();
4745 } );
4746
4747 if( it == end( cargo_parts ) ) {
4748 continue; // Can't find a cargo part matching the active item.
4749 }
4750 const item &target = *active_item_ref.item_ref;
4751 // Find the cargo part and coordinates corresponding to the current active item.
4752 const vehicle_part &pt = it->part();
4753 const tripoint item_loc = it->pos();
4754 auto items = cur_veh.get_items( static_cast<int>( it->part_index() ) );
4756 if( target.is_food() || target.is_food_container() || target.is_corpse() ) {
4757 const vpart_info &pti = pt.info();
4758 if( engine_heater_is_on ) {
4760 }
4761
4762 if( pt.enabled && pti.has_flag( VPFLAG_FRIDGE ) ) {
4764 } else if( pt.enabled && pti.has_flag( VPFLAG_FREEZER ) ) {
4766 }
4767 }
4768 if( !process_map_items( items, active_item_ref.item_ref, item_loc, flag ) ) {
4769 // If the item was NOT destroyed, we can skip the remainder,
4770 // which handles fallout from the vehicle being damaged.
4771 continue;
4772 }
4773
4774 // item does not exist anymore, might have been an exploding bomb,
4775 // check if the vehicle is still valid (does exist)
4776 if( !current_submap.contains_vehicle( &cur_veh ) ) {
4777 // Nope, vehicle is not in the vehicle list of the submap,
4778 // it might have moved to another submap (unlikely)
4779 // or be destroyed, anyway it does not need to be processed here
4780 return;
4781 }
4782
4783 // Vehicle still valid, reload the list of cargo parts,
4784 // the list of cargo parts might have changed (imagine a part with
4785 // a low index has been removed by an explosion, all the other
4786 // parts would move up to fill the gap).
4787 cargo_parts = cur_veh.get_any_parts( VPFLAG_CARGO );
4788 }
4789}
bool is_food_container() const
Definition: item.cpp:6608
bool is_corpse() const
Whether this is a corpse item.
Definition: item.cpp:6620
bool contains_vehicle(vehicle *)
Definition: submap.cpp:255
bool engine_on
Definition: vehicle.h:2014
vehicle_part_with_feature_range< std::string > get_parts_including_carried(std::string feature) const
Yields a range of parts of this vehicle that each have the given feature and are not broken or remove...
Definition: vehicle.cpp:2731
bool has_part(const std::string &flag, bool enabled=false) const
Check if vehicle has at least one unbroken part with specified flag.
Definition: vehicle.cpp:2561
active_item_cache active_items
Definition: vehicle.h:1889
vehicle_part_with_feature_range< std::string > get_any_parts(std::string feature) const
Yields a range of parts of this vehicle that each have the given feature and not removed.
Definition: vehicle.cpp:2745
point mount() const
Returns the mount point: the point in the vehicles own coordinate system.
Definition: vehicle.cpp:6791
static void process_vehicle_items(vehicle &cur_veh, int part)
Definition: map.cpp:4540
const vpart_info & info() const
Get part definition common to all parts of this type.
bool enabled
Definition: vehicle.h:412
@ VPFLAG_FLUIDTANK
Definition: veh_type.h:73
@ VPFLAG_FREEZER
Definition: veh_type.h:58
@ VPFLAG_FRIDGE
Definition: veh_type.h:57

References vehicle::active_items, submap::contains_vehicle(), vehicle_part::enabled, vehicle::engine_on, vehicle::get_any_parts(), active_item_cache::get_for_processing(), vehicle::get_items(), vehicle::get_parts_including_carried(), vpart_info::has_flag(), vehicle::has_part(), vehicle_part::info(), item::is_corpse(), item::is_food(), item::is_food_container(), vpart_position::mount(), process_map_items(), process_vehicle_items(), TEMP_FREEZER, TEMP_FRIDGE, TEMP_HEATER, TEMP_NORMAL, VPFLAG_CARGO, VPFLAG_FLUIDTANK, VPFLAG_FREEZER, and VPFLAG_FRIDGE.

Referenced by process_items_in_vehicles().

◆ process_items_in_vehicles()

void map::process_items_in_vehicles ( submap current_submap)
private

Definition at line 4702 of file map.cpp.

4703{
4704 // a copy, important if the vehicle list changes because a
4705 // vehicle got destroyed by a bomb (an active item!), this list
4706 // won't change, but veh_in_nonant will change.
4707 std::vector<vehicle *> vehicles;
4708 for( const auto &veh : current_submap.vehicles ) {
4709 vehicles.push_back( veh.get() );
4710 }
4711 for( auto &cur_veh : vehicles ) {
4712 if( !current_submap.contains_vehicle( cur_veh ) ) {
4713 // vehicle not in the vehicle list of the nonant, has been
4714 // destroyed (or moved to another nonant?)
4715 // Can't be sure that it still exists, so skip it
4716 continue;
4717 }
4718
4719 process_items_in_vehicle( *cur_veh, current_submap );
4720 }
4721}
void process_items_in_vehicle(vehicle &cur_veh, submap &current_submap)
Definition: map.cpp:4723

References submap::contains_vehicle(), process_items_in_vehicle(), and submap::vehicles.

Referenced by process_items().

◆ produce_sap()

void map::produce_sap ( const tripoint p,
const time_duration time_since_last_actualize 
)
protected

Produce sap on tapped maple trees.

Parameters
pLocation of tapped tree
time_since_last_actualizeTime since this function has been called the last time.

Definition at line 7317 of file map.cpp.

7318{
7319 if( time_since_last_actualize <= 0_turns ) {
7320 return;
7321 }
7322
7323 if( t_tree_maple_tapped != ter( p ) ) {
7324 return;
7325 }
7326
7327 // Amount of maple sap liters produced per season per tap
7328 static const int maple_sap_per_season = 56;
7329
7330 // How many turns to produce 1 charge (250 ml) of sap?
7331 const time_duration producing_length = 0.75 * calendar::season_length();
7332
7333 const time_duration turns_to_produce = producing_length / ( maple_sap_per_season * 4 );
7334
7335 // How long of this time_since_last_actualize have we been in the producing period (late winter, early spring)?
7336 time_duration time_producing = 0_turns;
7337
7338 if( time_since_last_actualize >= calendar::year_length() ) {
7339 time_producing = producing_length;
7340 } else {
7341 // We are only producing sap on the intersection with the sap producing season.
7342 const time_duration early_spring_end = 0.5f * calendar::season_length();
7343 const time_duration late_winter_start = 3.75f * calendar::season_length();
7344
7345 const time_point last_actualize = calendar::turn - time_since_last_actualize;
7346 const time_duration last_actualize_tof = time_past_new_year( last_actualize );
7347 bool last_producing = (
7348 last_actualize_tof >= late_winter_start ||
7349 last_actualize_tof < early_spring_end
7350 );
7351 const time_duration current_tof = time_past_new_year( calendar::turn );
7352 bool current_producing = (
7353 current_tof >= late_winter_start ||
7354 current_tof < early_spring_end
7355 );
7356
7357 const time_duration non_producing_length = 3.25 * calendar::season_length();
7358
7359 if( last_producing && current_producing ) {
7360 if( time_since_last_actualize < non_producing_length ) {
7361 time_producing = time_since_last_actualize;
7362 } else {
7363 time_producing = time_since_last_actualize - non_producing_length;
7364 }
7365 } else if( !last_producing && !current_producing ) {
7366 if( time_since_last_actualize > non_producing_length ) {
7367 time_producing = time_since_last_actualize - non_producing_length;
7368 }
7369 } else if( last_producing && !current_producing ) {
7370 // We hit the end of early spring
7371 if( last_actualize_tof < early_spring_end ) {
7372 time_producing = early_spring_end - last_actualize_tof;
7373 } else {
7374 time_producing = calendar::year_length() - last_actualize_tof + early_spring_end;
7375 }
7376 } else if( !last_producing && current_producing ) {
7377 // We hit the start of late winter
7378 if( current_tof >= late_winter_start ) {
7379 time_producing = current_tof - late_winter_start;
7380 } else {
7381 time_producing = 0.25f * calendar::season_length() + current_tof;
7382 }
7383 }
7384 }
7385
7386 int new_charges = roll_remainder( time_producing / turns_to_produce );
7387 // Not enough time to produce 1 charge of sap
7388 if( new_charges <= 0 ) {
7389 return;
7390 }
7391
7392 item sap( "maple_sap", calendar::turn );
7393
7394 // Is there a proper container?
7395 auto items = i_at( p );
7396 for( auto &it : items ) {
7397 if( it.is_bucket() || it.is_watertight_container() ) {
7398 const int capacity = it.get_remaining_capacity_for_liquid( sap, true );
7399 if( capacity > 0 ) {
7400 new_charges = std::min( new_charges, capacity );
7401
7402 // The environment might have poisoned the sap with animals passing by, insects, leaves or contaminants in the ground
7403 sap.poison = one_in( 10 ) ? 1 : 0;
7404 sap.charges = new_charges;
7405
7406 it.fill_with( sap );
7407 }
7408 // Only fill up the first container.
7409 break;
7410 }
7411 }
7412}
time_duration time_past_new_year(const time_point &p)
Definition: calendar.h:502
A point in the game time.
Definition: calendar.h:431
ter_id t_tree_maple_tapped
Definition: mapdata.cpp:683
time_duration year_length()
Definition: calendar.cpp:461
time_duration season_length()
Definition: calendar.cpp:466

References item::charges, i_at(), one_in(), item::poison, roll_remainder(), calendar::season_length(), t_tree_maple_tapped, ter(), time_past_new_year(), calendar::turn, and calendar::year_length().

Referenced by actualize().

◆ propagate_field()

void map::propagate_field ( const tripoint center,
const field_type_id type,
int  amount,
int  max_intensity = 0 
)

Definition at line 1941 of file map_field.cpp.

1943{
1944 using gas_blast = std::pair<float, tripoint>;
1945 std::priority_queue<gas_blast, std::vector<gas_blast>, pair_greater_cmp_first> open;
1946 std::set<tripoint> closed;
1947 open.push( { 0.0f, center } );
1948
1949 const bool not_gas = type.obj().phase != GAS;
1950
1951 while( amount > 0 && !open.empty() ) {
1952 if( closed.count( open.top().second ) ) {
1953 open.pop();
1954 continue;
1955 }
1956
1957 // All points with equal gas intensity should propagate at the same time
1958 std::list<gas_blast> gas_front;
1959 gas_front.push_back( open.top() );
1960 const int cur_intensity = get_field_intensity( open.top().second, type );
1961 open.pop();
1962 while( !open.empty() && get_field_intensity( open.top().second, type ) == cur_intensity ) {
1963 if( closed.count( open.top().second ) == 0 ) {
1964 gas_front.push_back( open.top() );
1965 }
1966
1967 open.pop();
1968 }
1969
1970 int increment = std::max<int>( 1, amount / gas_front.size() );
1971
1972 while( !gas_front.empty() ) {
1973 gas_blast gp = random_entry_removed( gas_front );
1974 closed.insert( gp.second );
1975 const int cur_intensity = get_field_intensity( gp.second, type );
1976 if( cur_intensity < max_intensity ) {
1977 const int bonus = std::min( max_intensity - cur_intensity, increment );
1978 mod_field_intensity( gp.second, type, bonus );
1979 amount -= bonus;
1980 } else {
1981 amount--;
1982 }
1983
1984 if( amount <= 0 ) {
1985 return;
1986 }
1987
1988 static const std::array<int, 8> x_offset = {{ -1, 1, 0, 0, 1, -1, -1, 1 }};
1989 static const std::array<int, 8> y_offset = {{ 0, 0, -1, 1, -1, 1, -1, 1 }};
1990 for( size_t i = 0; i < 8; i++ ) {
1991 tripoint pt = gp.second + point( x_offset[ i ], y_offset[ i ] );
1992 if( closed.count( pt ) > 0 ) {
1993 continue;
1994 }
1995
1996 if( impassable( pt ) && ( not_gas || !has_flag( TFLAG_PERMEABLE, pt ) ) ) {
1997 closed.insert( pt );
1998 continue;
1999 }
2000 if( !obstructed_by_vehicle_rotation( gp.second, pt ) ) {
2001 open.push( { static_cast<float>( rl_dist( center, pt ) ), pt } );
2002 }
2003 }
2004 }
2005 }
2006}
@ GAS
Definition: enums.h:175
Greater-than comparison operator; required by the sort interface.
Definition: cata_utility.h:16

References center, GAS, get_field_intensity(), has_flag(), impassable(), mod_field_intensity(), obstructed_by_vehicle_rotation(), open(), random_entry_removed(), rl_dist(), TFLAG_PERMEABLE, and type.

Referenced by computer_session::action_irradiator(), and emit_field().

◆ propagate_suspension_check()

void map::propagate_suspension_check ( const tripoint point)

Checks surrounding tiles for suspension, and has them check for collapse.

!!Should only be called after the tile at this point has been destroyed!!

Definition at line 3012 of file map.cpp.

3013{
3014 for( const tripoint &neighbor : points_in_radius( point, 1 ) ) {
3015 if( neighbor != point && has_flag( TFLAG_SUSPENDED, neighbor ) ) {
3016 collapse_invalid_suspension( neighbor );
3017 }
3018 }
3019}

References collapse_invalid_suspension(), has_flag(), points_in_radius(), and TFLAG_SUSPENDED.

Referenced by bash_ter_success(), collapse_at(), and collapse_invalid_suspension().

◆ put_items_from_loc()

std::vector< item * > map::put_items_from_loc ( const item_group_id loc,
const tripoint p,
const time_point turn = calendar::start_of_cataclysm 
)

Place items from an item group at p.

Places as much items as the item group says. (Most item groups are distributions and will only create one item.)

Parameters
locCurrent location of items
pDestination of items
turnThe birthday that the created items shall have.
Returns
Vector of pointers to placed items (can be empty, but no nulls).

Definition at line 5608 of file mapgen.cpp.

5610{
5611 const auto items = item_group::items_from( loc, turn );
5612 return spawn_items( p, items );
5613}

References item_group::items_from(), spawn_items(), and calendar::turn.

Referenced by add_corpse(), activity_handlers::forage_finish(), mapgen_cavern(), MapExtras::mx_corpses(), MapExtras::mx_grave(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), and place_items().

◆ rad_scorch()

void map::rad_scorch ( const tripoint p,
const time_duration time_since_last_actualize 
)
protected

Radiation-related plant (and fungus?) death.

Definition at line 7414 of file map.cpp.

7415{
7416 const int rads = get_radiation( p );
7417 if( rads == 0 ) {
7418 return;
7419 }
7420
7421 // TODO: More interesting rad scorch chance - base on season length?
7422 if( !x_in_y( 1.0 * rads * rads * time_since_last_actualize, 91_days ) ) {
7423 return;
7424 }
7425
7426 // First destroy the farmable plants (those are furniture)
7427 // TODO: Rad-resistant mutant plants (that produce radioactive fruit)
7428 const furn_t &fid = furn( p ).obj();
7429 if( fid.has_flag( "PLANT" ) ) {
7430 i_clear( p );
7431 furn_set( p, f_null );
7432 }
7433
7434 const ter_id tid = ter( p );
7435 // TODO: De-hardcode this
7436 static const std::map<ter_id, ter_str_id> dies_into {{
7437 {t_grass, ter_str_id( "t_dirt" )},
7438 {t_tree_young, ter_str_id( "t_dirt" )},
7439 {t_tree_pine, ter_str_id( "t_tree_deadpine" )},
7440 {t_tree_birch, ter_str_id( "t_tree_birch_harvested" )},
7441 {t_tree_willow, ter_str_id( "t_tree_willow_harvested" )},
7442 {t_tree_hickory, ter_str_id( "t_tree_hickory_dead" )},
7443 {t_tree_hickory_harvested, ter_str_id( "t_tree_hickory_dead" )},
7444 }};
7445
7446 const auto iter = dies_into.find( tid );
7447 if( iter != dies_into.end() ) {
7448 ter_set( p, iter->second );
7449 return;
7450 }
7451
7452 const ter_t &tr = tid.obj();
7453 if( tr.has_flag( "SHRUB" ) ) {
7454 ter_set( p, t_dirt );
7455 } else if( tr.has_flag( "TREE" ) ) {
7456 ter_set( p, ter_str_id( "t_tree_dead" ) );
7457 }
7458}
int get_radiation(const tripoint &p) const
Definition: map.cpp:4093
ter_id t_tree_hickory_harvested
Definition: mapdata.cpp:684
ter_id t_tree_willow
Definition: mapdata.cpp:683
ter_id t_tree_birch
Definition: mapdata.cpp:683
ter_id t_tree_pine
Definition: mapdata.cpp:683
ter_id t_tree_young
Definition: mapdata.cpp:679
ter_id t_tree_hickory
Definition: mapdata.cpp:684
string_id< ter_t > ter_str_id
Definition: mapdata.h:24

References f_null, furn(), furn_set(), get_radiation(), map_data_common_t::has_flag(), i_clear(), int_id< T >::obj(), t_dirt, t_grass, t_tree_birch, t_tree_hickory, t_tree_hickory_harvested, t_tree_pine, t_tree_willow, t_tree_young, ter(), ter_set(), and x_in_y().

Referenced by actualize().

◆ random_outdoor_tile()

point map::random_outdoor_tile ( )

Definition at line 2799 of file map.cpp.

2800{
2801 std::vector<point> options;
2802 for( const tripoint &p : points_on_zlevel() ) {
2803 if( is_outside( p.xy() ) ) {
2804 options.push_back( p.xy() );
2805 }
2806 }
2808}
std::string options()
Definition: path_info.cpp:238

References is_outside(), PATH_INFO::options(), point_north_west, points_on_zlevel(), and random_entry().

◆ ranged_target_size()

double map::ranged_target_size ( const tripoint p) const

Size of map objects at p for purposes of ranged combat.

Size is in percentage of tile: if 1.0, all attacks going through tile should hit map objects on it, if 0.0 there is nothing to be hit (air/water).

Definition at line 2013 of file map.cpp.

2014{
2015 if( impassable( p ) ) {
2016 return 1.0;
2017 }
2018
2019 if( !has_floor( p ) ) {
2020 return 0.0;
2021 }
2022
2023 // TODO: Handle cases like shrubs, trees, furniture, sandbags...
2024 return 0.1;
2025}

References has_floor(), and impassable().

Referenced by projectile_attack().

◆ reachable_flood_steps()

void map::reachable_flood_steps ( std::vector< tripoint > &  reachable_pts,
const tripoint f,
int  range,
int  cost_min,
int  cost_max 
) const

Populates a vector of points that are reachable within a number of steps from a point.

It could be generalized to take advantage of z levels, but would need some additional code to detect whether a valid transition was on a tile.

Does the following:

  1. Checks if a point is reachable using a flood fill and if it is, adds it to a vector.

Definition at line 6358 of file map.cpp.

6360{
6361 struct pq_item {
6362 int dist;
6363 int ndx;
6364 };
6365 struct pq_item_comp {
6366 bool operator()( const pq_item &left, const pq_item &right ) {
6367 return left.dist > right.dist;
6368 }
6369 };
6370 using PQ_type = std::priority_queue< pq_item, std::vector<pq_item>, pq_item_comp>;
6371
6372 // temp buffer for grid
6373 const int grid_dim = range * 2 + 1;
6374 // init to -1 as "not visited yet"
6375 std::vector< int > t_grid( static_cast<size_t>( grid_dim * grid_dim ), -1 );
6376 const tripoint origin_offset = {range, range, 0};
6377 const int initial_visit_distance = range * range; // Large unreachable value
6378
6379 // Fill positions that are visitable with initial_visit_distance
6380 for( const tripoint &p : points_in_radius( f, range ) ) {
6381 const tripoint tp = { p.xy(), f.z };
6382 const int tp_cost = move_cost( tp );
6383 // rejection conditions
6384 if( tp_cost < cost_min || tp_cost > cost_max || !has_floor_or_support( tp ) ) {
6385 continue;
6386 }
6387 // set initial cost for grid point
6388 tripoint origin_relative = tp - f;
6389 origin_relative += origin_offset;
6390 int ndx = origin_relative.x + origin_relative.y * grid_dim;
6391 t_grid[ ndx ] = initial_visit_distance;
6392 }
6393
6394 auto gen_neighbors = []( const pq_item & elem, int grid_dim, pq_item * neighbors ) {
6395 // Up to 8 neighbors
6396 int new_cost = elem.dist + 1;
6397 // *INDENT-OFF*
6398 int ox[8] = {
6399 -1, 0, 1,
6400 -1, 1,
6401 -1, 0, 1
6402 };
6403 int oy[8] = {
6404 -1, -1, -1,
6405 0, 0,
6406 1, 1, 1
6407 };
6408 // *INDENT-ON*
6409
6410 point e( elem.ndx % grid_dim, elem.ndx / grid_dim );
6411 for( int i = 0; i < 8; ++i ) {
6412 point n( e + point( ox[i], oy[i] ) );
6413
6414 int ndx = n.x + n.y * grid_dim;
6415 neighbors[i] = { new_cost, ndx };
6416 }
6417 };
6418
6419 PQ_type pq( pq_item_comp{} );
6420 pq_item first_item{ 0, range + range * grid_dim };
6421 pq.push( first_item );
6422 pq_item neighbor_elems[8];
6423
6424 while( !pq.empty() ) {
6425 const pq_item item = pq.top();
6426 pq.pop();
6427
6428 if( t_grid[ item.ndx ] == initial_visit_distance ) {
6429 t_grid[ item.ndx ] = item.dist;
6430 if( item.dist + 1 < range ) {
6431 gen_neighbors( item, grid_dim, neighbor_elems );
6432 for( pq_item neighbor_elem : neighbor_elems ) {
6433 pq.push( neighbor_elem );
6434 }
6435 }
6436 }
6437 }
6438 std::vector<char> o_grid( static_cast<size_t>( grid_dim * grid_dim ), 0 );
6439 for( int y = 0, ndx = 0; y < grid_dim; ++y ) {
6440 for( int x = 0; x < grid_dim; ++x, ++ndx ) {
6441 if( t_grid[ ndx ] != -1 && t_grid[ ndx ] < initial_visit_distance ) {
6442 // set self and neighbors to 1
6443 for( int dy = -1; dy <= 1; ++dy ) {
6444 for( int dx = -1; dx <= 1; ++dx ) {
6445 int tx = dx + x;
6446 int ty = dy + y;
6447
6448 if( tx >= 0 && tx < grid_dim && ty >= 0 && ty < grid_dim ) {
6449 o_grid[ tx + ty * grid_dim ] = 1;
6450 }
6451 }
6452 }
6453 }
6454 }
6455 }
6456
6457 // Now go over again to pull out all of the reachable points
6458 for( int y = 0, ndx = 0; y < grid_dim; ++y ) {
6459 for( int x = 0; x < grid_dim; ++x, ++ndx ) {
6460 if( o_grid[ ndx ] ) {
6461 tripoint t = f - origin_offset + tripoint{ x, y, 0 };
6462 reachable_pts.push_back( t );
6463 }
6464 }
6465 }
6466}

References has_floor_or_support(), left, move_cost(), points_in_radius(), right, point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, and tripoint::z.

Referenced by inventory::form_from_map(), and use_charges().

◆ register_vehicle_zone()

void map::register_vehicle_zone ( vehicle veh,
int  zlev 
)

Definition at line 1015 of file map.cpp.

1016{
1017 auto &ch = get_cache( zlev );
1018 ch.zone_vehicles.insert( veh );
1019}

References get_cache().

Referenced by zone_manager::create_vehicle_loot_zone(), and zone_manager::revert_vzones().

◆ remove_field()

void map::remove_field ( const tripoint p,
const field_type_id field_to_remove 
)

Remove field entry at xy, ignored if the field entry is not present.

Definition at line 5526 of file map.cpp.

5527{
5528 if( !inbounds( p ) ) {
5529 return;
5530 }
5531
5532 point l;
5533 submap *const current_submap = get_submap_at( p, l );
5534
5535 if( current_submap->get_field( l ).remove_field( field_to_remove ) ) {
5536 // Only adjust the count if the field actually existed.
5537 if( !--current_submap->field_count ) {
5538 get_cache( p.z ).field_cache.set( static_cast<size_t>( p.x / SEEX + ( (
5539 p.y / SEEX ) * MAPSIZE ) ) );
5540 }
5541 const auto &fdata = field_to_remove.obj();
5542 if( fdata.dirty_transparency_cache || !fdata.is_transparent() ) {
5545 }
5546 if( fdata.is_dangerous() ) {
5548 }
5549 }
5550}

References level_cache::field_cache, submap::field_count, get_cache(), submap::get_field(), get_submap_at(), inbounds(), MAPSIZE, int_id< T >::obj(), field::remove_field(), SEEX, set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_transparency_cache_dirty(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by computer_session::action_deactivate_shock_vent(), bash_field(), editmap::edit_fld(), iexamine::fireplace(), game::grabbed_furn_move(), MapExtras::mx_house_spider(), MapExtras::mx_spider(), game::process_artifact(), relic_funcs::process_recharge_entry(), set_field_intensity(), shoot(), smash(), spell_move(), avatar_funcs::try_to_sleep(), and game::walk_move().

◆ remove_rotten_items()

template<typename Container >
void map::remove_rotten_items ( Container &  items,
const tripoint p,
temperature_flag  temperature 
)
protected

Go through the list of items, update their rotten status and remove items that have rotten away completely.

Parameters
itemsitems to remove
pThe point on this map where the items are, used for rot calculation.
temperatureflag that overrides temperature processing at certain locations

Definition at line 7163 of file map.cpp.

7164{
7165 for( auto it = items.begin(); it != items.end(); ) {
7166 if( it->actualize_rot( pnt, temperature, get_weather() ) ) {
7167 if( it->is_comestible() ) {
7168 rotten_item_spawn( *it, pnt );
7169 }
7170 it = i_rem( pnt, it );
7171 } else {
7172 ++it;
7173 }
7174 }
7175}

References get_weather(), i_rem(), and rotten_item_spawn().

Referenced by actualize().

◆ remove_submap_camp()

void map::remove_submap_camp ( const tripoint p)

Definition at line 5641 of file map.cpp.

5642{
5643 get_submap_at( p )->camp.reset();
5644}

References submap::camp, and get_submap_at().

Referenced by basecamp::abandon_camp(), and game::validate_camps().

◆ remove_trap()

void map::remove_trap ( const tripoint p)

Definition at line 5334 of file map.cpp.

5335{
5336 if( !inbounds( p ) ) {
5337 return;
5338 }
5339
5340 point l;
5341 submap *const current_submap = get_submap_at( p, l );
5342
5343 trap_id tid = current_submap->get_trap( l );
5344 if( tid != tr_null ) {
5345 if( g != nullptr && this == &get_map() ) {
5346 g->u.add_known_trap( p, tr_null.obj() );
5347 }
5348
5349 current_submap->set_trap( l, tr_null );
5350 auto &traps = traplocs[tid.to_i()];
5351 const auto iter = std::find( traps.begin(), traps.end(), p );
5352 if( iter != traps.end() ) {
5353 traps.erase( iter );
5354 }
5355 }
5356}
void set_trap(point p, trap_id trap)
Definition: submap.h:77

References detail::find(), g, get_map(), get_submap_at(), submap::get_trap(), inbounds(), int_id< T >::obj(), submap::set_trap(), int_id< T >::to_i(), tr_null, and traplocs.

Referenced by complete_construction(), vehicle::handle_trap(), trapfunc::map_regen(), mremove_trap(), trap::on_disarmed(), game::process_artifact(), relic_funcs::process_recharge_entry(), and trap_set().

◆ reset_vehicle_cache()

void map::reset_vehicle_cache ( )

Definition at line 312 of file map.cpp.

313{
316
317 // Cache all vehicles
318 const int zmin = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
319 const int zmax = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
320 for( int zlev = zmin; zlev <= zmax; zlev++ ) {
321 auto &ch = get_cache( zlev );
322 for( const auto &elem : ch.vehicle_list ) {
323 elem->adjust_zlevel( 0, tripoint_zero );
324 add_vehicle_to_cache( elem );
325 }
326 }
327}
void clear_vehicle_cache()
Definition: map.cpp:371

References abs_sub, add_vehicle_to_cache(), clear_vehicle_cache(), get_cache(), last_full_vehicle_list_dirty, OVERMAP_DEPTH, OVERMAP_HEIGHT, tripoint_zero, tripoint::z, and zlevels.

Referenced by veh_interact::complete_vehicle(), detach_vehicle(), editmap::draw_main_ui_overlay(), load(), loadn(), editmap::mapgen_preview(), editmap::mapgen_veh_destroy(), rotate(), shift(), and vehicle::use_bike_rack().

◆ restock_fruits()

void map::restock_fruits ( const tripoint p,
const time_duration time_since_last_actualize 
)
protected

Try to grow fruits on static plants (not planted by the player)

Parameters
pPlace to restock
time_since_last_actualizeTime since this function has been called the last time.

Definition at line 7303 of file map.cpp.

7304{
7305 const auto &ter = this->ter( p ).obj();
7306 if( !ter.has_flag( TFLAG_HARVESTED ) ) {
7307 return; // Already harvestable. Do nothing.
7308 }
7309 // Make it harvestable again if the last actualization was during a different season or year.
7310 const time_point last_touched = calendar::turn - time_since_last_actualize;
7311 if( season_of_year( calendar::turn ) != season_of_year( last_touched ) ||
7312 time_since_last_actualize >= calendar::season_length() ) {
7313 ter_set( p, ter.transforms_into );
7314 }
7315}
season_type season_of_year(const time_point &p)
Definition: calendar.cpp:547

References int_id< T >::obj(), calendar::season_length(), season_of_year(), ter(), ter_set(), TFLAG_HARVESTED, and calendar::turn.

Referenced by actualize(), and saven().

◆ restore_vision_transparency_cache()

void map::restore_vision_transparency_cache ( const tripoint center,
int  target_z,
float(&)  vision_restore_cache[9],
bool(&)  blocked_restore_cache[8] 
)
protected

Definition at line 1352 of file lightmap.cpp.

1354{
1355 auto &map_cache = get_cache( target_z );
1356 float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.transparency_cache;
1357 diagonal_blocks( &blocked_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.vehicle_obscured_cache;
1358
1359 int i = 0;
1360 for( point adjacent : eight_adjacent_offsets ) {
1361 const tripoint p = center + adjacent;
1362 if( !inbounds( p ) ) {
1363 continue;
1364 }
1365 transparency_cache[p.x][p.y] = vision_restore_cache[i];
1366
1367 if( blocked_restore_cache[i] ) {
1368 bool &relevant_blocked = adjacent == point_north_east ? blocked_cache[center.x][center.y].ne :
1369 adjacent == point_south_east ? blocked_cache[p.x][p.y].nw :
1370 adjacent == point_south_west ? blocked_cache[p.x][p.y].ne :
1371 /* point_north_west */ blocked_cache[center.x][center.y].nw;
1372 relevant_blocked = false;
1373 }
1374
1375 i++;
1376 }
1377 transparency_cache[center.x][center.y] = vision_restore_cache[8];
1378}

References center, eight_adjacent_offsets, get_cache(), inbounds(), MAPSIZE_X, MAPSIZE_Y, point_north_east, point_south_east, point_south_west, tripoint::x, and tripoint::y.

Referenced by build_seen_cache().

◆ rotate()

void map::rotate ( int  turns,
bool  setpos_safe = false 
)

Rotates this map, and all of its contents, by the specified multiple of 90 degrees.

Parameters
turnsHow many 90-degree turns to rotate the map.

Definition at line 5835 of file mapgen.cpp.

5836{
5837
5838 //Handle anything outside the 1-3 range gracefully; rotate(0) is a no-op.
5839 turns = turns % 4;
5840 if( turns == 0 ) {
5841 return;
5842 }
5843
5844 real_coords rc;
5845 const tripoint &abs_sub = get_abs_sub();
5846 rc.fromabs( point( abs_sub.x * SEEX, abs_sub.y * SEEY ) );
5847
5848 // TODO: This radius can be smaller - how small?
5849 const int radius = HALF_MAPSIZE + 3;
5850 // uses submap coordinates
5851 // TODO: fix point types
5852 const std::vector<shared_ptr_fast<npc>> npcs =
5854 for( const shared_ptr_fast<npc> &i : npcs ) {
5855 npc &np = *i;
5856 const tripoint sq = np.global_square_location();
5857 const point local_sq = getlocal( sq ).xy();
5858
5859 real_coords np_rc;
5860 np_rc.fromabs( sq.xy() );
5861 // Note: We are rotating the entire overmap square (2x2 of submaps)
5862 if( np_rc.om_pos != rc.om_pos || sq.z != abs_sub.z ) {
5863 continue;
5864 }
5865
5866 // OK, this is ugly: we remove the NPC from the whole map
5867 // Then we place it back from scratch
5868 // It could be rewritten to utilize the fact that rotation shouldn't cross overmaps
5869
5870 point old( np_rc.sub_pos );
5871 if( np_rc.om_sub.x % 2 != 0 ) {
5872 old.x += SEEX;
5873 }
5874 if( np_rc.om_sub.y % 2 != 0 ) {
5875 old.y += SEEY;
5876 }
5877
5878 const point new_pos = old .rotate( turns, { SEEX * 2, SEEY * 2 } );
5879 if( setpos_safe ) {
5880 // setpos can't be used during mapgen, but spawn_at_precise clips position
5881 // to be between 0-11,0-11 and teleports NPCs when used inside of update_mapgen
5882 // calls
5883 const tripoint new_global_sq = sq - local_sq + new_pos;
5884 np.setpos( get_map().getlocal( new_global_sq ) );
5885 } else {
5886 // OK, this is ugly: we remove the NPC from the whole map
5887 // Then we place it back from scratch
5888 // It could be rewritten to utilize the fact that rotation shouldn't cross overmaps
5890 np.spawn_at_precise( { abs_sub.xy() }, { new_pos, abs_sub.z } );
5892 }
5893 }
5894
5897
5898 // Move the submaps around.
5899 if( turns == 2 ) {
5902 } else {
5903 point p;
5904 submap tmp;
5905
5907
5908 for( int k = 0; k < 4; ++k ) {
5909 p = p.rotate( turns, { 2, 2 } );
5911 }
5912 }
5913
5914 // Then rotate them and recalculate vehicle positions.
5915 for( int j = 0; j < 2; ++j ) {
5916 for( int i = 0; i < 2; ++i ) {
5917 point p( i, j );
5918 auto sm = get_submap_at_grid( p );
5919
5920 sm->rotate( turns );
5921
5922 for( auto &veh : sm->vehicles ) {
5923 veh->sm_pos = tripoint( p, abs_sub.z );
5924 }
5925
5927 }
5928 }
5930
5931 // rotate zones
5933 mgr.rotate_zones( *this, turns );
5934}
shared_ptr_fast< npc > npc_ptr
Definition: basecamp.h:46
character_id getID() const
Definition: character.cpp:483
void clear_vehicle_list(int zlev)
Definition: map.cpp:389
void setpos(const tripoint &pos) override
Note: this places NPC on a given position in CURRENT MAP coordinates.
Definition: npc.cpp:688
void spawn_at_precise(point submap_offset, const tripoint &square)
As spawn_at, but also sets position within the submap.
Definition: npc.cpp:736
tripoint global_square_location() const override
Global position, expressed in map square coordinate system (the most detailed coordinate system),...
Definition: npc.cpp:746
std::vector< shared_ptr_fast< npc > > get_npcs_near(const tripoint_abs_sm &p, int radius)
Get all npcs in a area with given radius around given central point.
shared_ptr_fast< npc > remove_npc(const character_id &id)
Find npc by id and if found, erase it from the npc list and return it ( or return nullptr if not foun...
void rotate_zones(map &target_map, int turns)
Definition: clzones.cpp:1052
coords::coord_point< tripoint, coords::origin::abs, coords::sm > tripoint_abs_sm
Definition: coordinates.h:490
static constexpr int HALF_MAPSIZE
void swap(colony< element_type, element_allocator_type, element_skipfield_type > &a, colony< element_type, element_allocator_type, element_skipfield_type > &b) COLONY_NOEXCEPT_SWAP(element_allocator_type)
Swaps colony A's contents with that of colony B.
Definition: colony.h:3496
point rotate(int turns, point dim={ 1, 1 }) const
Rotate point clockwise.
Definition: point.cpp:10
point om_sub
Definition: coordinates.h:638
void fromabs(point abs)
Definition: coordinates.cpp:3
point om_pos
Definition: coordinates.h:637
point sub_pos
Definition: coordinates.h:635

References abs_sub, clear_vehicle_cache(), clear_vehicle_list(), real_coords::fromabs(), get_abs_sub(), zone_manager::get_manager(), get_map(), overmapbuffer::get_npcs_near(), get_submap_at_grid(), Character::getID(), getlocal(), npc::global_square_location(), HALF_MAPSIZE, overmapbuffer::insert_npc(), real_coords::om_pos, real_coords::om_sub, overmap_buffer, point_east, point_south, point_south_east, point_zero, overmapbuffer::remove_npc(), reset_vehicle_cache(), point::rotate(), zone_manager::rotate_zones(), SEEX, SEEY, npc::setpos(), coords::sm, npc::spawn_at_precise(), real_coords::sub_pos, cata::swap(), update_vehicle_list(), point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, and tripoint::z.

Referenced by draw_connections(), draw_lab(), draw_office_tower(), draw_triffid(), mapgen_function_json::generate(), mapgen_ants_curved(), mapgen_ants_straight(), mapgen_ants_tee(), mapgen_forest_trail_curved(), mapgen_forest_trail_straight(), mapgen_forest_trail_tee(), mapgen_highway(), mapgen_parking_lot(), editmap::mapgen_preview(), mapgen_railroad(), mapgen_railroad_bridge(), mapgen_river_curved(), mapgen_river_curved_not(), mapgen_river_straight(), mapgen_road(), mapgen_rotate(), mapgen_sewer_curved(), mapgen_sewer_straight(), mapgen_sewer_tee(), mapgen_subway(), and update_mapgen_function_json::update_map().

◆ rotten_item_spawn()

void map::rotten_item_spawn ( const item item,
const tripoint p 
)

Checks to see if the item that is rotting away generates a creature when it does.

Parameters
itemitem that is spawning creatures
pThe point on this map where the item is and creature will be

Definition at line 7177 of file map.cpp.

7178{
7179 if( g->critter_at( pnt ) != nullptr ) {
7180 return;
7181 }
7182 const auto &comest = item.get_comestible();
7183 mongroup_id mgroup = comest->rot_spawn;
7184 if( !mgroup ) {
7185 return;
7186 }
7187 const int chance = static_cast<int>( comest->rot_spawn_chance *
7188 get_option<float>( "CARRION_SPAWNRATE" ) );
7189 if( rng( 0, 100 ) < chance ) {
7191 add_spawn( spawn_details.name, 1, pnt, false );
7192 if( g->u.sees( pnt ) ) {
7193 if( item.is_seed() ) {
7194 add_msg( m_warning, _( "Something has crawled out of the %s plants!" ), item.get_plant_name() );
7195 } else {
7196 add_msg( m_warning, _( "Something has crawled out of the %s!" ), item.tname() );
7197 }
7198 }
7199 }
7200}
const cata::value_ptr< islot_comestible > & get_comestible() const
Definition: item.cpp:10119
std::string get_plant_name() const
The name of the plant as it appears in the various informational menus.
Definition: item.cpp:9788
bool is_seed() const
Whether this is actually a seed, the seed functions won't be of much use for non-seeds.
Definition: item.cpp:9769

References _, add_msg(), add_spawn(), g, item::get_comestible(), item::get_plant_name(), MonsterGroupManager::GetResultFromGroup(), item::is_seed(), m_warning, MonsterGroupResult::name, rng(), and item::tname().

Referenced by grow_plant(), item::process_internal(), and remove_rotten_items().

◆ route()

std::vector< tripoint > map::route ( const tripoint f,
const tripoint t,
const pathfinding_settings settings,
const std::set< tripoint > &  pre_closed = {{ }} 
) const

Calculate the best path using A*.

Parameters
fThe source location from which to path.
tThe destination to which to path.
settingsStructure describing pathfinding parameters.
pre_closedNever path through those points. They can still be the source or the destination.

Definition at line 194 of file pathfinding.cpp.

197{
198 /* TODO: If the origin or destination is out of bound, figure out the closest
199 * in-bounds point and go to that, then to the real origin/destination.
200 */
201 std::vector<tripoint> ret;
202
203 if( f == t || !inbounds( f ) ) {
204 return ret;
205 }
206
207 if( !inbounds( t ) ) {
208 tripoint clipped = t;
209 clip_to_bounds( clipped );
210 return route( f, clipped, settings, pre_closed );
211 }
212 // First, check for a simple straight line on flat ground
213 // Except when the line contains a pre-closed tile - we need to do regular pathing then
214 static const auto non_normal = PF_SLOW | PF_WALL | PF_VEHICLE | PF_TRAP | PF_SHARP;
215 if( f.z == t.z ) {
216 const auto line_path = line_to( f, t );
217 const auto &pf_cache = get_pathfinding_cache_ref( f.z );
218 // Check all points for any special case (including just hard terrain)
219 if( !( pf_cache.special[f.x][f.y] & non_normal ) &&
220 std::all_of( line_path.begin(), line_path.end(), [&pf_cache]( const tripoint & p ) {
221 return !( pf_cache.special[p.x][p.y] & non_normal );
222 } ) ) {
223 const std::set<tripoint> sorted_line( line_path.begin(), line_path.end() );
224
225 if( is_disjoint( sorted_line, pre_closed ) ) {
226 return line_path;
227 }
228 }
229 }
230
231 // If expected path length is greater than max distance, allow only line path, like above
232 if( rl_dist( f, t ) > settings.max_dist ) {
233 return ret;
234 }
235
236 int max_length = settings.max_length;
237 int bash = settings.bash_strength;
238 int climb_cost = settings.climb_cost;
239 bool doors = settings.allow_open_doors;
240 bool trapavoid = settings.avoid_traps;
241 bool roughavoid = settings.avoid_rough_terrain;
242 bool sharpavoid = settings.avoid_sharp;
243
244 const int pad = 16; // Should be much bigger - low value makes pathfinders dumb!
245 int minx = std::min( f.x, t.x ) - pad;
246 int miny = std::min( f.y, t.y ) - pad;
247 // TODO: Make this way bigger
248 int minz = std::min( f.z, t.z );
249 int maxx = std::max( f.x, t.x ) + pad;
250 int maxy = std::max( f.y, t.y ) + pad;
251 // Same TODO: as above
252 int maxz = std::max( f.z, t.z );
253 clip_to_bounds( minx, miny, minz );
254 clip_to_bounds( maxx, maxy, maxz );
255
256 pathfinder pf( point( minx, miny ), point( maxx, maxy ) );
257 // Make NPCs not want to path through player
258 // But don't make player pathing stop working
259 for( const auto &p : pre_closed ) {
260 if( p.x >= minx && p.x < maxx && p.y >= miny && p.y < maxy ) {
261 pf.close_point( p );
262 }
263 }
264
265 // Start and end must not be closed
266 pf.unclose_point( f );
267 pf.unclose_point( t );
268 pf.add_point( 0, 0, f, f );
269
270 bool done = false;
271
272 do {
273 auto cur = pf.get_next();
274
275 const int parent_index = flat_index( cur );
276 auto &layer = pf.get_layer( cur.z );
277 auto &cur_state = layer.state[parent_index];
278 if( cur_state == ASL_CLOSED ) {
279 continue;
280 }
281
282 if( layer.gscore[parent_index] > max_length ) {
283 // Shortest path would be too long, return empty vector
284 return std::vector<tripoint>();
285 }
286
287 if( cur == t ) {
288 done = true;
289 break;
290 }
291
292 cur_state = ASL_CLOSED;
293
294 const auto &pf_cache = get_pathfinding_cache_ref( cur.z );
295 const auto cur_special = pf_cache.special[cur.x][cur.y];
296
297 int cur_part;
298 const vehicle *cur_veh = veh_at_internal( cur, cur_part );
299
300 // 7 3 5
301 // 1 . 2
302 // 6 4 8
303 constexpr std::array<int, 8> x_offset{{ -1, 1, 0, 0, 1, -1, -1, 1 }};
304 constexpr std::array<int, 8> y_offset{{ 0, 0, -1, 1, -1, 1, -1, 1 }};
305 for( size_t i = 0; i < 8; i++ ) {
306 const tripoint p( cur.x + x_offset[i], cur.y + y_offset[i], cur.z );
307 const int index = flat_index( p );
308
309 // TODO: Remove this and instead have sentinels at the edges
310 if( p.x < minx || p.x >= maxx || p.y < miny || p.y >= maxy ) {
311 continue;
312 }
313
314 if( layer.state[index] == ASL_CLOSED ) {
315 continue;
316 }
317
318 int part = -1;
319 const vehicle *veh = veh_at_internal( p, part );
320 if( cur_veh &&
321 !cur_veh->allowed_move( cur_veh->tripoint_to_mount( cur ), cur_veh->tripoint_to_mount( p ) ) ) {
322 //Trying to squeeze through a vehicle hole, skip this movement but don't close the tile as other paths may lead to it
323 continue;
324 }
325
326 if( veh && veh != cur_veh &&
327 !veh->allowed_move( veh->tripoint_to_mount( cur ), veh->tripoint_to_mount( p ) ) ) {
328 //Same as above but moving into rather than out of a vehicle
329 continue;
330 }
331
332 // Penalize for diagonals or the path will look "unnatural"
333 int newg = layer.gscore[parent_index] + ( ( cur.x != p.x && cur.y != p.y ) ? 1 : 0 );
334
335 const auto p_special = pf_cache.special[p.x][p.y];
336 // TODO: De-uglify, de-huge-n
337 if( !( p_special & non_normal ) ) {
338 // Boring flat dirt - the most common case above the ground
339 newg += 2;
340 } else {
341 if( roughavoid ) {
342 layer.state[index] = ASL_CLOSED; // Close all rough terrain tiles
343 continue;
344 }
345
346 const maptile &tile = maptile_at_internal( p );
347 const auto &terrain = tile.get_ter_t();
348 const auto &furniture = tile.get_furn_t();
349
350 const int cost = move_cost_internal( furniture, terrain, veh, part );
351 // Don't calculate bash rating unless we intend to actually use it
352 const int rating = ( bash == 0 || cost != 0 ) ? -1 :
353 bash_rating_internal( bash, furniture, terrain, false, veh, part );
354
355 if( cost == 0 && rating <= 0 && ( !doors || !terrain.open || !furniture.open ) && veh == nullptr &&
356 climb_cost <= 0 ) {
357 layer.state[index] = ASL_CLOSED; // Close it so that next time we won't try to calculate costs
358 continue;
359 }
360
361 newg += cost;
362 if( cost == 0 ) {
363 if( climb_cost > 0 && p_special & PF_CLIMBABLE ) {
364 // Climbing fences
365 newg += climb_cost;
366 } else if( doors && ( terrain.open || furniture.open ) &&
367 ( !terrain.has_flag( "OPENCLOSE_INSIDE" ) || !furniture.has_flag( "OPENCLOSE_INSIDE" ) ||
368 !is_outside( cur ) ) ) {
369 // Only try to open INSIDE doors from the inside
370 // To open and then move onto the tile
371 newg += 4;
372 } else if( veh != nullptr ) {
373 const auto vpobst = vpart_position( const_cast<vehicle &>( *veh ), part ).obstacle_at_part();
374 part = vpobst ? vpobst->part_index() : -1;
375 int dummy = -1;
376 if( doors && veh->part_flag( part, VPFLAG_OPENABLE ) &&
377 ( !veh->part_flag( part, "OPENCLOSE_INSIDE" ) ||
378 veh_at_internal( cur, dummy ) == veh ) ) {
379 // Handle car doors, but don't try to path through curtains
380 newg += 10; // One turn to open, 4 to move there
381 } else if( part >= 0 && bash > 0 ) {
382 // Car obstacle that isn't a door
383 // TODO: Account for armor
384 int hp = veh->cpart( part ).hp();
385 if( hp / 20 > bash ) {
386 // Threshold damage thing means we just can't bash this down
387 layer.state[index] = ASL_CLOSED;
388 continue;
389 } else if( hp / 10 > bash ) {
390 // Threshold damage thing means we will fail to deal damage pretty often
391 hp *= 2;
392 }
393
394 newg += 2 * hp / bash + 8 + 4;
395 } else if( part >= 0 ) {
396 if( !doors || !veh->part_flag( part, VPFLAG_OPENABLE ) ) {
397 // Won't be openable, don't try from other sides
398 layer.state[index] = ASL_CLOSED;
399 }
400
401 continue;
402 }
403 } else if( rating > 1 ) {
404 // Expected number of turns to bash it down, 1 turn to move there
405 // and 5 turns of penalty not to trash everything just because we can
406 newg += ( 20 / rating ) + 2 + 10;
407 } else if( rating == 1 ) {
408 // Desperate measures, avoid whenever possible
409 newg += 500;
410 } else {
411 // Unbashable and unopenable from here
412 if( !doors || !terrain.open || !furniture.open ) {
413 // Or anywhere else for that matter
414 layer.state[index] = ASL_CLOSED;
415 }
416
417 continue;
418 }
419 }
420
421 if( trapavoid && p_special & PF_TRAP ) {
422 const auto &ter_trp = terrain.trap.obj();
423 const auto &trp = ter_trp.is_benign() ? tile.get_trap_t() : ter_trp;
424 if( !trp.is_benign() ) {
425 // For now make them detect all traps
426 if( has_zlevels() && terrain.has_flag( TFLAG_NO_FLOOR ) ) {
427 // Special case - ledge in z-levels
428 // Warning: really expensive, needs a cache
429 if( valid_move( p, tripoint( p.xy(), p.z - 1 ), false, true ) ) {
430 tripoint below( p.xy(), p.z - 1 );
431 if( !has_flag( TFLAG_NO_FLOOR, below ) ) {
432 // Otherwise this would have been a huge fall
433 auto &layer = pf.get_layer( p.z - 1 );
434 // From cur, not p, because we won't be walking on air
435 pf.add_point( layer.gscore[parent_index] + 10,
436 layer.score[parent_index] + 10 + 2 * rl_dist( below, t ),
437 cur, below );
438 }
439
440 // Close p, because we won't be walking on it
441 layer.state[index] = ASL_CLOSED;
442 continue;
443 }
444 } else if( trapavoid ) {
445 // Otherwise it's walkable
446 newg += 500;
447 }
448 }
449 }
450
451 if( sharpavoid && p_special & PF_SHARP ) {
452 layer.state[index] = ASL_CLOSED; // Avoid sharp things
453 }
454
455 }
456
457 // If not visited, add as open
458 // If visited, add it only if we can do so with better score
459 if( layer.state[index] == ASL_NONE || newg < layer.gscore[index] ) {
460 pf.add_point( newg, newg + 2 * rl_dist( p, t ), cur, p );
461 }
462 }
463
464 if( !has_zlevels() || !( cur_special & PF_UPDOWN ) || !settings.allow_climb_stairs ) {
465 // The part below is only for z-level pathing
466 continue;
467 }
468
469 const maptile &parent_tile = maptile_at_internal( cur );
470 const auto &parent_terrain = parent_tile.get_ter_t();
471 if( settings.allow_climb_stairs && cur.z > minz && parent_terrain.has_flag( TFLAG_GOES_DOWN ) ) {
472 tripoint dest( cur.xy(), cur.z - 1 );
473 if( vertical_move_destination<TFLAG_GOES_UP>( *this, dest ) ) {
474 auto &layer = pf.get_layer( dest.z );
475 pf.add_point( layer.gscore[parent_index] + 2,
476 layer.score[parent_index] + 2 * rl_dist( dest, t ),
477 cur, dest );
478 }
479 }
480 if( settings.allow_climb_stairs && cur.z < maxz && parent_terrain.has_flag( TFLAG_GOES_UP ) ) {
481 tripoint dest( cur.xy(), cur.z + 1 );
482 if( vertical_move_destination<TFLAG_GOES_DOWN>( *this, dest ) ) {
483 auto &layer = pf.get_layer( dest.z );
484 pf.add_point( layer.gscore[parent_index] + 2,
485 layer.score[parent_index] + 2 * rl_dist( dest, t ),
486 cur, dest );
487 }
488 }
489 if( cur.z < maxz && parent_terrain.has_flag( TFLAG_RAMP ) &&
490 valid_move( cur, tripoint( cur.xy(), cur.z + 1 ), false, true ) ) {
491 auto &layer = pf.get_layer( cur.z + 1 );
492 for( size_t it = 0; it < 8; it++ ) {
493 const tripoint above( cur.x + x_offset[it], cur.y + y_offset[it], cur.z + 1 );
494 pf.add_point( layer.gscore[parent_index] + 4,
495 layer.score[parent_index] + 4 + 2 * rl_dist( above, t ),
496 cur, above );
497 }
498 }
499 if( cur.z < maxz && parent_terrain.has_flag( TFLAG_RAMP_UP ) &&
500 valid_move( cur, tripoint( cur.xy(), cur.z + 1 ), false, true, true ) ) {
501 auto &layer = pf.get_layer( cur.z + 1 );
502 for( size_t it = 0; it < 8; it++ ) {
503 const tripoint above( cur.x + x_offset[it], cur.y + y_offset[it], cur.z + 1 );
504 pf.add_point( layer.gscore[parent_index] + 4,
505 layer.score[parent_index] + 4 + 2 * rl_dist( above, t ),
506 cur, above );
507 }
508 }
509 if( cur.z > minz && parent_terrain.has_flag( TFLAG_RAMP_DOWN ) &&
510 valid_move( cur, tripoint( cur.xy(), cur.z - 1 ), false, true, true ) ) {
511 auto &layer = pf.get_layer( cur.z - 1 );
512 for( size_t it = 0; it < 8; it++ ) {
513 const tripoint below( cur.x + x_offset[it], cur.y + y_offset[it], cur.z - 1 );
514 pf.add_point( layer.gscore[parent_index] + 4,
515 layer.score[parent_index] + 4 + 2 * rl_dist( below, t ),
516 cur, below );
517 }
518 }
519
520 } while( !done && !pf.empty() );
521
522 if( done ) {
523 ret.reserve( rl_dist( f, t ) * 2 );
524 tripoint cur = t;
525 // Just to limit max distance, in case something weird happens
526 for( int fdist = max_length; fdist != 0; fdist-- ) {
527 const int cur_index = flat_index( cur );
528 const auto &layer = pf.get_layer( cur.z );
529 const tripoint &par = layer.parent[cur_index];
530 if( cur == f ) {
531 break;
532 }
533
534 ret.push_back( cur );
535 // Jumps are acceptable on 1 z-level changes
536 // This is because stairs teleport the player too
537 if( rl_dist( cur, par ) > 1 && std::abs( cur.z - par.z ) != 1 ) {
538 debugmsg( "Jump in our route! %d:%d:%d->%d:%d:%d",
539 cur.x, cur.y, cur.z, par.x, par.y, par.z );
540 return ret;
541 }
542
543 cur = par;
544 }
545
546 std::reverse( ret.begin(), ret.end() );
547 }
548
549 return ret;
550}
bool has_zlevels() const
Definition: map.h:1623
const pathfinding_cache & get_pathfinding_cache_ref(int zlev) const
Definition: map.cpp:8907
point tripoint_to_mount(const tripoint &p) const
Definition: vehicle.cpp:3131
const vehicle_part & cpart(int part_num) const
Definition: vehicle.cpp:7089
bool part_flag(int p, const std::string &f) const
Definition: vehicle.cpp:2912
bool allowed_move(point from, point to) const
Definition: vehicle.cpp:3221
@ TFLAG_GOES_DOWN
Definition: mapdata.h:308
@ TFLAG_GOES_UP
Definition: mapdata.h:309
Definition: gates.h:28
Definition: overmap.h:50
bool is_disjoint(const Set1 &set1, const Set2 &set2)
constexpr int flat_index(const tripoint &p)
Definition: pathfinding.cpp:34
@ ASL_CLOSED
Definition: pathfinding.cpp:30
@ ASL_NONE
Definition: pathfinding.cpp:28
@ PF_VEHICLE
Definition: pathfinding.h:11
@ PF_WALL
Definition: pathfinding.h:10
@ PF_CLIMBABLE
Definition: pathfinding.h:15
@ PF_UPDOWN
Definition: pathfinding.h:14
@ PF_TRAP
Definition: pathfinding.h:13
@ PF_SHARP
Definition: pathfinding.h:16
@ PF_SLOW
Definition: pathfinding.h:9
@ hp
Drains HP to recharge.
const trap & get_trap_t() const
Definition: submap.h:264
@ VPFLAG_OPENABLE
Definition: veh_type.h:44

References pathfinding_settings::allow_climb_stairs, pathfinding_settings::allow_open_doors, vehicle::allowed_move(), ASL_CLOSED, ASL_NONE, pathfinding_settings::avoid_rough_terrain, pathfinding_settings::avoid_sharp, pathfinding_settings::avoid_traps, bash(), bash_rating_internal(), pathfinding_settings::bash_strength, pathfinding_settings::climb_cost, clip_to_bounds(), vehicle::cpart(), debugmsg, detail::digits::done, flat_index(), furniture, maptile::get_furn_t(), get_pathfinding_cache_ref(), maptile::get_ter_t(), maptile::get_trap_t(), has_flag(), has_zlevels(), hp, vehicle_part::hp(), inbounds(), is_disjoint(), is_outside(), line_to(), maptile_at_internal(), pathfinding_settings::max_dist, pathfinding_settings::max_length, move_cost_internal(), vpart_position::obstacle_at_part(), vehicle::part_flag(), PF_CLIMBABLE, PF_SHARP, PF_SLOW, PF_TRAP, PF_UPDOWN, PF_VEHICLE, PF_WALL, cata::hash64_detail::ret, rl_dist(), route(), terrain, TFLAG_GOES_DOWN, TFLAG_GOES_UP, TFLAG_NO_FLOOR, TFLAG_RAMP, TFLAG_RAMP_DOWN, TFLAG_RAMP_UP, vehicle::tripoint_to_mount(), valid_move(), veh_at_internal(), VPFLAG_OPENABLE, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by activity_on_turn_move_loot(), add_item_or_charges(), Character::can_mount(), npc::go_to_omt_destination(), game::handle_action(), game::list_items(), game::look_around(), perform_zone_activity_turn(), route(), route_adjacent(), activity_handlers::travel_do_turn(), game::try_get_left_click_action(), and npc::update_path().

◆ save()

void map::save ( )

Add currently loaded submaps (in grid) to the mapbuffer.

They will than be stored by that class and can be loaded from that class. This can be called several times, the mapbuffer takes care of adding the same submap several times. It should only be called after the map has been loaded. Submaps that have been loaded from the mapbuffer (and not generated) are already stored in the mapbuffer. TODO: determine if this is really needed? Submaps are already in the mapbuffer if they have been loaded from disc and the are added by map::generate, too. So when do they not appear in the mapbuffer?

Definition at line 6668 of file map.cpp.

6669{
6670 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
6671 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6672 if( zlevels ) {
6673 for( int gridz = -OVERMAP_DEPTH; gridz <= OVERMAP_HEIGHT; gridz++ ) {
6674 saven( tripoint( gridx, gridy, gridz ) );
6675 }
6676 } else {
6677 saven( tripoint( gridx, gridy, abs_sub.z ) );
6678 }
6679 }
6680 }
6681}

References abs_sub, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, saven(), tripoint::z, and zlevels.

Referenced by start_location::add_map_extra(), add_monsters(), start_location::burn(), talk_function::buy_100_logs(), talk_function::buy_10_logs(), create_lab_consoles(), construct::done_digormine_stair(), construct::done_mine_upstair(), farm_action(), talk_function::field_build_1(), talk_function::field_build_2(), talk_function::field_harvest(), talk_function::field_plant(), defense_game::init_map(), mission_start::kill_horde_master(), talk_function::loot_building(), om_cutdown_trees(), om_harvest_furn(), om_harvest_itm(), om_harvest_ter(), om_set_hide_site(), mission_start::place_deposit_box(), mission_start::place_dog(), mission_start::place_npc_software(), mission_start::place_priest_diary(), basecamp::place_results(), game::place_vehicle_nearby(), mission_start::place_zombie_mom(), start_location::prepare_map(), mission_start::ranch_nurse_1(), mission_start::ranch_nurse_2(), mission_start::ranch_nurse_3(), mission_start::ranch_nurse_4(), mission_start::ranch_nurse_5(), mission_start::ranch_nurse_6(), mission_start::ranch_nurse_7(), mission_start::ranch_nurse_8(), mission_start::ranch_nurse_9(), mission_start::ranch_scavenger_1(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), mission_start::reveal_lab_train_depot(), game::save_maps(), and debug_menu::spawn_nested_mapgen().

◆ saven()

void map::saven ( const tripoint grid)
protected

Definition at line 7011 of file map.cpp.

7012{
7013 dbg( DL::Debug ) << "map::saven( world=" << abs_sub << ", grid=" << grid << " )";
7014 const int gridn = get_nonant( grid );
7015 submap *submap_to_save = getsubmap( gridn );
7016 if( submap_to_save == nullptr || submap_to_save->get_ter( point_zero ) == t_null ) {
7017 // This is a serious error and should be signaled as soon as possible
7018 debugmsg( "map::saven grid (%s) %s!", grid.to_string(),
7019 submap_to_save == nullptr ? "null" : "uninitialized" );
7020 return;
7021 }
7022
7023 const tripoint abs = abs_sub.xy() + grid;
7024
7025 if( !zlevels && grid.z != abs_sub.z ) {
7026 debugmsg( "Tried to save submap (%d,%d,%d) as (%d,%d,%d), which isn't supported in non-z-level builds",
7027 abs.x, abs.y, abs_sub.z, abs.x, abs.y, grid.z );
7028 }
7029
7030 dbg( DL::Debug ) << "map::saven abs: " << abs << " gridn: " << gridn;
7031
7032 // An edge case: restock_fruits relies on last_touched, so we must call it before save
7033 if( season_of_year( calendar::turn ) != season_of_year( submap_to_save->last_touched ) ) {
7034 const time_duration time_since_last_actualize = calendar::turn - submap_to_save->last_touched;
7035 for( int x = 0; x < SEEX; x++ ) {
7036 for( int y = 0; y < SEEY; y++ ) {
7037 const tripoint pnt = sm_to_ms_copy( grid ) + point( x, y );
7038 restock_fruits( pnt, time_since_last_actualize );
7039 }
7040 }
7041 }
7042
7043 submap_to_save->last_touched = calendar::turn;
7044 MAPBUFFER.add_submap( abs, submap_to_save );
7045}
bool add_submap(const tripoint &p, std::unique_ptr< submap > &sm)
Add a new submap to the buffer.
Definition: mapbuffer.cpp:68
@ Debug
Debug information (default: disabled).

References abs_sub, mapbuffer::add_submap(), dbg, Debug, debugmsg, get_nonant(), submap::get_ter(), getsubmap(), grid, submap::last_touched, MAPBUFFER, point_zero, restock_fruits(), season_of_year(), SEEX, SEEY, sm_to_ms_copy(), t_null, calendar::turn, tripoint::xy(), tripoint::z, and zlevels.

Referenced by generate(), and save().

◆ scent_blockers()

void map::scent_blockers ( std::array< std::array< char, MAPSIZE_X >, MAPSIZE_Y > &  scent_transfer,
point  min,
point  max 
)

Build the map of scent-resistant tiles.

Should be way faster than if done in game.cpp using public map functions.

Definition at line 8619 of file map.cpp.

8621{
8622 auto reduce = TFLAG_REDUCE_SCENT;
8623 auto block = TFLAG_NO_SCENT;
8624 auto fill_values = [&]( const tripoint & gp, const submap * sm, point lp ) {
8625 // We need to generate the x/y coordinates, because we can't get them "for free"
8626 const point p = lp + sm_to_ms_copy( gp.xy() );
8627 if( sm->get_ter( lp ).obj().has_flag( block ) ) {
8628 scent_transfer[p.x][p.y] = 0;
8629 } else if( sm->get_ter( lp ).obj().has_flag( reduce ) ||
8630 sm->get_furn( lp ).obj().has_flag( reduce ) ) {
8631 scent_transfer[p.x][p.y] = 1;
8632 } else {
8633 scent_transfer[p.x][p.y] = 5;
8634 }
8635
8636 return ITER_CONTINUE;
8637 };
8638
8639 function_over( tripoint( min, abs_sub.z ), tripoint( max, abs_sub.z ), fill_values );
8640
8641 const inclusive_rectangle<point> local_bounds( min, max );
8642
8643 // Now vehicles
8644
8645 auto vehs = get_vehicles();
8646 for( auto &wrapped_veh : vehs ) {
8647 vehicle &veh = *( wrapped_veh.v );
8648 for( const vpart_reference &vp : veh.get_any_parts( VPFLAG_OBSTACLE ) ) {
8649 const tripoint part_pos = vp.pos();
8650 if( local_bounds.contains( part_pos.xy() ) && scent_transfer[part_pos.x][part_pos.y] == 5 ) {
8651 scent_transfer[part_pos.x][part_pos.y] = 1;
8652 }
8653 }
8654
8655 // Doors, but only the closed ones
8656 for( const vpart_reference &vp : veh.get_any_parts( VPFLAG_OPENABLE ) ) {
8657 if( vp.part().open ) {
8658 continue;
8659 }
8660
8661 const tripoint part_pos = vp.pos();
8662 if( local_bounds.contains( part_pos.xy() ) && scent_transfer[part_pos.x][part_pos.y] == 5 ) {
8663 scent_transfer[part_pos.x][part_pos.y] = 1;
8664 }
8665 }
8666 }
8667}
void function_over(const tripoint &start, const tripoint &end, Functor fun) const
Runs a functor over given submaps over submaps in the area, getting next submap only when the current...
Definition: map.cpp:8565
@ TFLAG_REDUCE_SCENT
Definition: mapdata.h:278
@ TFLAG_NO_SCENT
Definition: mapdata.h:284
@ VPFLAG_OBSTACLE
Definition: veh_type.h:42

References abs_sub, inclusive_rectangle< Point, >::contains(), function_over(), vehicle::get_any_parts(), get_vehicles(), ITER_CONTINUE, coords::sm, sm_to_ms_copy(), TFLAG_NO_SCENT, TFLAG_REDUCE_SCENT, VPFLAG_OBSTACLE, VPFLAG_OPENABLE, point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, and tripoint::z.

Referenced by scent_map::update().

◆ sees() [1/2]

bool map::sees ( const tripoint F,
const tripoint T,
int  range 
) const

Returns whether F sees T with a view range of range.

Definition at line 6203 of file map.cpp.

6204{
6205 int dummy = 0;
6206 return sees( F, T, range, dummy );
6207}

References sees().

Referenced by apply_ammo_effects(), find_clear_path(), mattack::flame(), explosion_handler::explosion_funcs::flashbang(), get_heat_radiation(), projectile_attack(), Creature::sees(), sees(), Character::sees_with_infrared(), shake_vehicle(), shoot(), spawn_monsters_submap_group(), and vehicle_selector::vehicle_selector().

◆ sees() [2/2]

bool map::sees ( const tripoint F,
const tripoint T,
int  range,
int &  bresenham_slope 
) const
private

Don't expose the slope adjust outside map functions.

This one is internal-only, we don't want to expose the slope tweaking ickiness outside the map class.

Parameters
FThing doing the seeing
TThing being seen
rangeVision range of F
bresenham_slopeIndicates the start offset of Bresenham line used to connect the two points, and may subsequently be used to form a path between them. Set to zero if the function returns false.

Definition at line 6212 of file map.cpp.

6214{
6215 if( ( range >= 0 && range < rl_dist( F, T ) ) ||
6216 !inbounds( T ) ) {
6217 bresenham_slope = 0;
6218 return false; // Out of range!
6219 }
6220 // Cannonicalize the order of the tripoints so the cache is reflexive.
6221 const tripoint &min = F < T ? F : T;
6222 const tripoint &max = !( F < T ) ? F : T;
6223 // A little gross, just pack the values into a point.
6224 const point key(
6225 min.x << 16 | min.y << 8 | ( min.z + OVERMAP_DEPTH ),
6226 max.x << 16 | max.y << 8 | ( max.z + OVERMAP_DEPTH )
6227 );
6228 char cached = skew_vision_cache.get( key, -1 );
6229 if( cached >= 0 ) {
6230 return cached > 0;
6231 }
6232
6233 bool visible = true;
6234
6235 // Ugly `if` for now
6236 if( !fov_3d || F.z == T.z ) {
6237
6238 point last_point = F.xy();
6239 bresenham( F.xy(), T.xy(), bresenham_slope,
6240 [this, &visible, &T, &last_point]( point new_point ) {
6241 // Exit before checking the last square, it's still visible even if opaque.
6242 if( new_point.x == T.x && new_point.y == T.y ) {
6243 return false;
6244 }
6245 if( !this->is_transparent( tripoint( new_point, T.z ) ) ||
6246 obscured_by_vehicle_rotation( tripoint( last_point, T.z ), tripoint( new_point, T.z ) ) ) {
6247 visible = false;
6248 return false;
6249 }
6250 last_point = new_point;
6251 return true;
6252 } );
6253 skew_vision_cache.insert( 100000, key, visible ? 1 : 0 );
6254 return visible;
6255 }
6256
6257 tripoint last_point = F;
6258 bresenham( F, T, bresenham_slope, 0,
6259 [this, &visible, &T, &last_point]( const tripoint & new_point ) {
6260 // Exit before checking the last square if it's not a vertical transition,
6261 // it's still visible even if opaque.
6262 if( new_point == T && last_point.z == T.z ) {
6263 return false;
6264 }
6265
6266 // TODO: Allow transparent floors (and cache them!)
6267 if( new_point.z == last_point.z ) {
6268 if( !this->is_transparent( new_point ) || obscured_by_vehicle_rotation( last_point, new_point ) ) {
6269 visible = false;
6270 return false;
6271 }
6272 } else {
6273 const int max_z = std::max( new_point.z, last_point.z );
6274 if( ( has_floor_or_support( {new_point.xy(), max_z} ) ||
6275 !is_transparent( {new_point.xy(), last_point.z} ) ) &&
6276 ( has_floor_or_support( {last_point.xy(), max_z} ) ||
6277 !is_transparent( {last_point.xy(), new_point.z} ) ) ) {
6278 visible = false;
6279 return false;
6280 }
6281 }
6282
6283 last_point = new_point;
6284 return true;
6285 } );
6286 skew_vision_cache.insert( 100000, key, visible ? 1 : 0 );
6287 return visible;
6288}

References bresenham(), fov_3d, inbounds(), obscured_by_vehicle_rotation(), OVERMAP_DEPTH, rl_dist(), skew_vision_cache, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

◆ sees_some_items() [1/2]

bool map::sees_some_items ( const tripoint p,
const Creature who 
) const

Check if creature can see some items at p.

Includes:

  • check for items at this location (has_items(p))
  • check for SEALED flag (sealed furniture/terrain makes items not visible under any circumstances).
  • check for CONTAINER flag (makes items only visible when the creature is at p or at an adjacent square).

Definition at line 4795 of file map.cpp.

4796{
4797 // Can only see items if there are any items.
4798 return has_items( p ) && could_see_items( p, who.pos() );
4799}

References could_see_items(), has_items(), and Creature::pos().

Referenced by game::butcher(), editmap::draw_main_ui_overlay(), draw_maptile(), npc::find_corpse_to_pulp(), npc::find_item(), game::find_nearby_items(), vehicle::interact_with(), game::print_items_info(), and npc::see_item_say_smth().

◆ sees_some_items() [2/2]

bool map::sees_some_items ( const tripoint p,
const tripoint from 
) const

Definition at line 4801 of file map.cpp.

4802{
4803 return has_items( p ) && could_see_items( p, from );
4804}

References could_see_items(), and has_items().

◆ set() [1/2]

void map::set ( const tripoint p,
const ter_id new_terrain,
const furn_id new_furniture 
)

Definition at line 1377 of file map.cpp.

1378{
1379 furn_set( p, new_furniture );
1380 ter_set( p, new_terrain );
1381}

References furn_set(), and ter_set().

Referenced by farm_action(), talk_function::field_plant(), mapgen_function_json_base::formatted_set_incredibly_simple(), and activity_handlers::plant_seed_finish().

◆ set() [2/2]

void map::set ( point  p,
const ter_id new_terrain,
const furn_id new_furniture 
)
inline

Definition at line 773 of file map.h.

773 {
774 furn_set( p, new_furniture );
775 ter_set( p, new_terrain );
776 }

References furn_set(), and ter_set().

◆ set_abs_sub()

void map::set_abs_sub ( const tripoint p)
protected

Sets abs_sub, see there.

Uses the same coordinate system as abs_sub.

Definition at line 8345 of file map.cpp.

8346{
8347 abs_sub = p;
8348}

References abs_sub.

Referenced by fake_map::fake_map(), generate(), load(), shift(), and vertical_shift().

◆ set_field_age()

time_duration map::set_field_age ( const tripoint p,
const field_type_id type,
const time_duration age,
bool  isoffset = false 
)

Set age of field entry at point.

Parameters
pLocation of field
typeID of field
ageNew age of specified field
isoffsetIf true, the given age value is added to the existing value, if false, the existing age is ignored and overridden.
Returns
resulting age or -1_turns if not present (does not create a new field).

Definition at line 5400 of file map.cpp.

5402{
5403 if( field_entry *const field_ptr = get_field( p, type ) ) {
5404 return field_ptr->set_field_age( ( isoffset ? field_ptr->get_field_age() : 0_turns ) + age );
5405 }
5406 return -1_turns;
5407}

References get_field(), and type.

Referenced by game::grabbed_furn_move(), mod_field_age(), and game::walk_move().

◆ set_field_intensity()

int map::set_field_intensity ( const tripoint p,
const field_type_id type,
int  new_intensity,
bool  isoffset = false 
)

Set intensity of field entry at point, creating if not present, removing if intensity becomes 0.

Parameters
pLocation of field
typeID of field
new_intensityNew intensity of field
isoffsetIf true, the given new_intensity value is added to the existing value, if false, the existing intensity is ignored and overridden.
Returns
resulting intensity, or 0 for not present (either removed or not created at all).

Definition at line 5413 of file map.cpp.

5416{
5417 field_entry *field_ptr = get_field( p, type );
5418 if( field_ptr != nullptr ) {
5419 int adj = ( isoffset ? field_ptr->get_field_intensity() : 0 ) + new_intensity;
5420 if( adj > 0 ) {
5421 field_ptr->set_field_intensity( adj );
5422 return adj;
5423 } else {
5424 remove_field( p, type );
5425 return 0;
5426 }
5427 } else if( 0 + new_intensity > 0 ) {
5428 return add_field( p, type, new_intensity ) ? new_intensity : 0;
5429 }
5430
5431 return 0;
5432}

References add_field(), get_field(), field_entry::get_field_intensity(), remove_field(), field_entry::set_field_intensity(), and type.

Referenced by editmap::edit_fld(), game::grabbed_furn_move(), mod_field_intensity(), spell_move(), and game::walk_move().

◆ set_floor_cache_dirty()

void map::set_floor_cache_dirty ( const int  zlev)

◆ set_graffiti()

void map::set_graffiti ( const tripoint p,
const std::string &  contents 
)

Definition at line 7877 of file map.cpp.

7878{
7879 if( !inbounds( p ) ) {
7880 return;
7881 }
7882 point l;
7883 submap *const current_submap = get_submap_at( p, l );
7884 current_submap->set_graffiti( l, contents );
7885}
void set_graffiti(point p, const std::string &new_graffiti)
Definition: submap.cpp:132

References get_submap_at(), inbounds(), and submap::set_graffiti().

Referenced by jmapgen_graffiti::apply().

◆ set_memory_seen_cache_dirty()

void map::set_memory_seen_cache_dirty ( const tripoint p)

Definition at line 8899 of file map.cpp.

8900{
8901 const int offset = p.x + p.y * MAPSIZE_Y;
8902 if( offset >= 0 && offset < MAPSIZE_X * MAPSIZE_Y ) {
8903 get_cache( p.z ).map_memory_seen_cache.reset( offset );
8904 }
8905}

References get_cache(), level_cache::map_memory_seen_cache, MAPSIZE_X, MAPSIZE_Y, tripoint::x, tripoint::y, and tripoint::z.

Referenced by vehicle::damage_direct(), furn_set(), vehicle::stop(), and ter_set().

◆ set_outside_cache_dirty()

void map::set_outside_cache_dirty ( const int  zlev)

◆ set_pathfinding_cache_dirty()

void map::set_pathfinding_cache_dirty ( int  zlev)

◆ set_radiation() [1/2]

void map::set_radiation ( const tripoint p,
int  value 
)

Definition at line 4105 of file map.cpp.

4106{
4107 if( !inbounds( p ) ) {
4108 return;
4109 }
4110
4111 point l;
4112 submap *const current_submap = get_submap_at( p, l );
4113
4114 current_submap->set_radiation( l, value );
4115}

References get_submap_at(), inbounds(), and submap::set_radiation().

Referenced by jmapgen_setmap::apply(), create_anomaly(), draw_lab(), mapgen_crater(), mapgen_null(), mapgen_test(), and set_radiation().

◆ set_radiation() [2/2]

void map::set_radiation ( point  p,
const int  value 
)
inline

Definition at line 1153 of file map.h.

1153 {
1154 set_radiation( tripoint( p, abs_sub.z ), value );
1155 }

References abs_sub, set_radiation(), and tripoint::z.

◆ set_seen_cache_dirty() [1/2]

void map::set_seen_cache_dirty ( const int  zlevel)

Definition at line 241 of file map.cpp.

242{
243 if( inbounds_z( zlevel ) ) {
244 level_cache &cache = get_cache( zlevel );
245 cache.seen_cache_dirty = true;
246 }
247}

References get_cache(), inbounds_z(), and level_cache::seen_cache_dirty.

◆ set_seen_cache_dirty() [2/2]

void map::set_seen_cache_dirty ( const tripoint  change_location)

Definition at line 206 of file map.cpp.

207{
208 if( inbounds( change_location ) ) {
209 level_cache &cache = get_cache( change_location.z );
210 if( cache.seen_cache_dirty ) {
211 return;
212 }
213 if( cache.seen_cache[change_location.x][change_location.y] != 0.0 ||
214 cache.camera_cache[change_location.x][change_location.y] != 0.0 ) {
215 cache.seen_cache_dirty = true;
216 }
217 }
218}

References level_cache::camera_cache, get_cache(), inbounds(), level_cache::seen_cache, level_cache::seen_cache_dirty, tripoint::x, tripoint::y, and tripoint::z.

Referenced by add_field(), draw_fill_background(), furn_set(), loadn(), trapfunc::map_regen(), vehicle::merge_rackable_vehicle(), vehicle::open_or_close(), process_fields_in_submap(), remove_field(), avatar::set_movement_mode(), DefaultRemovePartHandler::set_transparency_cache_dirty(), vehicle::split_vehicles(), ter_set(), and weather_manager::update_weather().

◆ set_signage()

void map::set_signage ( const tripoint p,
const std::string &  message 
) const

Definition at line 4070 of file map.cpp.

4071{
4072 if( !inbounds( p ) ) {
4073 return;
4074 }
4075
4076 point l;
4077 submap *const current_submap = get_submap_at( p, l );
4078
4079 current_submap->set_signage( l, message );
4080}
void set_signage(point p, const std::string &s)
Definition: submap.cpp:172
std::string message
Definition: mapgen.cpp:411

References get_submap_at(), inbounds(), mapgen_defer::message, and submap::set_signage().

Referenced by jmapgen_sign::apply(), MapExtras::mx_grave(), MapExtras::mx_minefield(), and iexamine::sign().

◆ set_suspension_cache_dirty()

void map::set_suspension_cache_dirty ( const int  zlev)

Definition at line 227 of file map.cpp.

228{
229 if( inbounds_z( zlev ) ) {
230 get_cache( zlev ).suspension_cache_dirty = true;
231 }
232}

References get_cache(), inbounds_z(), and level_cache::suspension_cache_dirty.

Referenced by loadn(), editmap::mapgen_preview(), and ter_set().

◆ set_temperature() [1/2]

void map::set_temperature ( const tripoint p,
int  temperature 
)

Definition at line 4139 of file map.cpp.

4140{
4141 if( !inbounds( p ) ) {
4142 return;
4143 }
4144
4145 get_submap_at( p )->set_temperature( new_temperature );
4146}
void set_temperature(int new_temperature)
Definition: submap.h:169

References get_submap_at(), inbounds(), and submap::set_temperature().

Referenced by draw_lab(), and set_temperature().

◆ set_temperature() [2/2]

void map::set_temperature ( point  p,
int  new_temperature 
)
inline

Definition at line 1170 of file map.h.

1170 {
1171 set_temperature( tripoint( p, abs_sub.z ), new_temperature );
1172 }

References abs_sub, set_temperature(), and tripoint::z.

◆ set_transparency_cache_dirty() [1/2]

void map::set_transparency_cache_dirty ( const int  zlev)

◆ set_transparency_cache_dirty() [2/2]

void map::set_transparency_cache_dirty ( const tripoint p)

Definition at line 249 of file map.cpp.

250{
251 if( inbounds( p ) ) {
252 const tripoint smp = ms_to_sm_copy( p );
253 get_cache( smp.z ).transparency_cache_dirty.set( smp.x * MAPSIZE + smp.y );
254 }
255}

References get_cache(), inbounds(), MAPSIZE, ms_to_sm_copy(), level_cache::transparency_cache_dirty, tripoint::x, tripoint::y, and tripoint::z.

◆ setsubmap()

void map::setsubmap ( size_t  grididx,
submap smap 
)
protected

Set the submap pointer in grid at the give index.

This is the inverse of getsubmap, any existing pointer is overwritten. The index must be valid. The given submap pointer must not be null.

Definition at line 8364 of file map.cpp.

8365{
8366 if( grididx >= grid.size() ) {
8367 debugmsg( "Tried to access invalid grid index %d", grididx );
8368 return;
8369 } else if( smap == nullptr ) {
8370 debugmsg( "Tried to set NULL submap pointer at index %d", grididx );
8371 return;
8372 }
8373 grid[grididx] = smap;
8374}

References debugmsg, and grid.

Referenced by copy_grid(), fake_map::fake_map(), generate(), and loadn().

◆ shake_vehicle()

units::angle map::shake_vehicle ( vehicle veh,
int  velocity_before,
units::angle  direction 
)
Strength reduces chance of being thrown from your seat when not wearing a seatbelt Strength reduces chance of being thrown from your seat when not wearing a seatbelt Dexterity reduces chance of losing control of vehicle when shaken Driving reduces chance of losing control of vehicle when shaken Strength reduces distance thrown from seat in a vehicle impact

Definition at line 1650 of file vehicle_move.cpp.

1652{
1653 const int d_vel = std::abs( veh.velocity - velocity_before ) / 100;
1654
1655 std::vector<rider_data> riders = veh.get_riders();
1656
1657 units::angle coll_turn = 0_degrees;
1658 for( const rider_data &r : riders ) {
1659 const int ps = r.prt;
1660 Creature *rider = r.psg;
1661 if( rider == nullptr ) {
1662 debugmsg( "throw passenger: empty passenger at part %d", ps );
1663 continue;
1664 }
1665
1666 const tripoint part_pos = veh.global_part_pos3( ps );
1667 if( rider->pos() != part_pos ) {
1668 debugmsg( "throw passenger: passenger at %d,%d,%d, part at %d,%d,%d",
1669 rider->posx(), rider->posy(), rider->posz(),
1670 part_pos.x, part_pos.y, part_pos.z );
1672 continue;
1673 }
1674
1675 player *psg = dynamic_cast<player *>( rider );
1676 monster *pet = dynamic_cast<monster *>( rider );
1677
1678 bool throw_from_seat = false;
1679 int move_resist = 1;
1680 if( psg ) {
1681 ///\EFFECT_STR reduces chance of being thrown from your seat when not wearing a seatbelt
1682 move_resist = psg->str_cur * 150 + 500;
1683 } else {
1684 int pet_resist = 0;
1685 if( pet != nullptr ) {
1686 pet_resist = static_cast<int>( to_kilogram( pet->get_weight() ) * 200 );
1687 }
1688 move_resist = std::max( 100, pet_resist );
1689 }
1690 if( veh.part_with_feature( ps, VPFLAG_SEATBELT, true ) == -1 ) {
1691 ///\EFFECT_STR reduces chance of being thrown from your seat when not wearing a seatbelt
1692 throw_from_seat = d_vel * rng( 80, 120 ) > move_resist;
1693 }
1694
1695 // Damage passengers if d_vel is too high
1696 if( !throw_from_seat && ( 10 * d_vel ) > 6 * rng( 50, 100 ) ) {
1697 const int dmg = d_vel * rng( 70, 100 ) / 400;
1698 if( psg ) {
1699 psg->hurtall( dmg, nullptr );
1701 _( "You take %d damage by the power of the impact!" ),
1702 _( "<npcname> takes %d damage by the power of the "
1703 "impact!" ), dmg );
1704 } else {
1705 pet->apply_damage( nullptr, bodypart_id( "torso" ), dmg );
1706 }
1707 }
1708
1709 if( psg && veh.player_in_control( *psg ) ) {
1710 const int lose_ctrl_roll = rng( 0, d_vel );
1711 ///\EFFECT_DEX reduces chance of losing control of vehicle when shaken
1712
1713 ///\EFFECT_DRIVING reduces chance of losing control of vehicle when shaken
1714 if( lose_ctrl_roll > psg->dex_cur * 2 + psg->get_skill_level( skill_driving ) * 3 ) {
1716 _( "You lose control of the %s." ),
1717 _( "<npcname> loses control of the %s." ), veh.name );
1718 int turn_amount = rng( 1, 3 ) * std::sqrt( std::abs( veh.velocity ) ) / 30;
1719 if( turn_amount < 1 ) {
1720 turn_amount = 1;
1721 }
1722 units::angle turn_angle = std::min( turn_amount * 15_degrees, 120_degrees );
1723 coll_turn = one_in( 2 ) ? turn_angle : -turn_angle;
1724 }
1725 }
1726
1727 if( throw_from_seat ) {
1728 if( psg ) {
1730 _( "You are hurled from the %s's seat by "
1731 "the power of the impact!" ),
1732 _( "<npcname> is hurled from the %s's seat by "
1733 "the power of the impact!" ), veh.name );
1734 unboard_vehicle( part_pos );
1735 } else if( get_player_character().sees( part_pos ) ) {
1736 add_msg( m_bad, _( "The %s is hurled from %s's by the power of the impact!" ),
1737 pet->disp_name(), veh.name );
1738 }
1739 ///\EFFECT_STR reduces distance thrown from seat in a vehicle impact
1740 g->fling_creature( rider, direction + rng_float( -30_degrees, 30_degrees ),
1741 std::max( 10, d_vel - move_resist / 100 ) );
1742 }
1743 }
1744
1745 return coll_turn;
1746}
int dex_cur
Definition: character.h:257
int get_skill_level(const skill_id &ident) const
Definition: character.cpp:3317
units::mass get_weight() const override
Definition: monster.cpp:2706
std::string disp_name(bool possessive=false, bool capitalize_first=false) const override
Definition: monster.cpp:537
@ VPFLAG_SEATBELT
Definition: veh_type.h:45
static const skill_id skill_driving("driving")

References _, add_msg(), player::add_msg_player_or_npc(), monster::apply_damage(), debugmsg, Character::dex_cur, monster::disp_name(), g, get_player_character(), vehicle::get_riders(), Character::get_skill_level(), monster::get_weight(), vehicle::global_part_pos3(), Character::hurtall(), m_bad, m_warning, vehicle::name, one_in(), vehicle::part(), vehicle::part_with_feature(), vehicle_part::passenger_flag, vehicle::player_in_control(), Creature::pos(), Creature::posx(), Creature::posy(), Creature::posz(), vehicle_part::remove_flag(), rng(), rng_float(), sees(), skill_driving, Character::str_cur, units::to_kilogram(), unboard_vehicle(), vehicle::velocity, VPFLAG_SEATBELT, tripoint::x, tripoint::y, and tripoint::z.

Referenced by move_vehicle().

◆ shift()

void map::shift ( point  s)

Shift the map along the vector s.

This is like loading the map with coordinates derived from the current position of the map (abs_sub) plus the shift vector. Note: the map must have been loaded before this can be called.

Definition at line 6840 of file map.cpp.

6841{
6842 // Special case of 0-shift; refresh the map
6843 if( sp == point_zero ) {
6844 return; // Skip this?
6845 }
6846
6847 if( std::abs( sp.x ) > 1 || std::abs( sp.y ) > 1 ) {
6848 debugmsg( "map::shift called with a shift of more than one submap" );
6849 }
6850
6851 const tripoint abs = get_abs_sub();
6852
6853 set_abs_sub( abs + sp );
6854
6855 // if player is in vehicle, (s)he must be shifted with vehicle too
6856 if( g->u.in_vehicle ) {
6857 g->u.setx( g->u.posx() - sp.x * SEEX );
6858 g->u.sety( g->u.posy() - sp.y * SEEY );
6859 }
6860
6861 g->shift_destination_preview( point( -sp.x * SEEX, -sp.y * SEEY ) );
6862
6863 shift_traps( tripoint( sp, 0 ) );
6864
6865 vehicle *remoteveh = g->remoteveh();
6866
6867 const int zmin = zlevels ? -OVERMAP_DEPTH : abs.z;
6868 const int zmax = zlevels ? OVERMAP_HEIGHT : abs.z;
6869 for( int gridz = zmin; gridz <= zmax; gridz++ ) {
6870 for( vehicle *veh : get_cache( gridz ).vehicle_list ) {
6871 veh->zones_dirty = true;
6872 }
6873 }
6874
6875 constexpr half_open_rectangle<point> boundaries_2d( point_zero, point( MAPSIZE_Y, MAPSIZE_X ) );
6876 const point shift_offset_pt( -sp.x * SEEX, -sp.y * SEEY );
6877
6878 // Clear vehicle list and rebuild after shift
6880 // Shift the map sx submaps to the right and sy submaps down.
6881 // sx and sy should never be bigger than +/-1.
6882 // absx and absy are our position in the world, for saving/loading purposes.
6883 for( int gridz = zmin; gridz <= zmax; gridz++ ) {
6884 clear_vehicle_list( gridz );
6885 shift_bitset_cache<MAPSIZE_X, SEEX>( get_cache( gridz ).map_memory_seen_cache, sp );
6886 shift_bitset_cache<MAPSIZE, 1>( get_cache( gridz ).field_cache, sp );
6887 if( sp.x >= 0 ) {
6888 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
6889 if( sp.y >= 0 ) {
6890 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6891 if( ( sp.x > 0 && gridx == 0 ) || ( sp.y > 0 && gridy == 0 ) ) {
6892 submaps_with_active_items.erase( { abs.x + gridx, abs.y + gridy, gridz } );
6893 }
6894 if( gridx + sp.x < my_MAPSIZE && gridy + sp.y < my_MAPSIZE ) {
6895 copy_grid( tripoint( gridx, gridy, gridz ),
6896 tripoint( gridx + sp.x, gridy + sp.y, gridz ) );
6897 update_vehicle_list( get_submap_at_grid( {gridx, gridy, gridz} ), gridz );
6898 } else {
6899 loadn( tripoint( gridx, gridy, gridz ), true );
6900 }
6901 }
6902 } else { // sy < 0; work through it backwards
6903 for( int gridy = my_MAPSIZE - 1; gridy >= 0; gridy-- ) {
6904 if( ( sp.x > 0 && gridx == 0 ) || gridy == my_MAPSIZE - 1 ) {
6905 submaps_with_active_items.erase( { abs.x + gridx, abs.y + gridy, gridz } );
6906 }
6907 if( gridx + sp.x < my_MAPSIZE && gridy + sp.y >= 0 ) {
6908 copy_grid( tripoint( gridx, gridy, gridz ),
6909 tripoint( gridx + sp.x, gridy + sp.y, gridz ) );
6910 update_vehicle_list( get_submap_at_grid( { gridx, gridy, gridz } ), gridz );
6911 } else {
6912 loadn( tripoint( gridx, gridy, gridz ), true );
6913 }
6914 }
6915 }
6916 }
6917 } else { // sx < 0; work through it backwards
6918 for( int gridx = my_MAPSIZE - 1; gridx >= 0; gridx-- ) {
6919 if( sp.y >= 0 ) {
6920 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6921 if( gridx == my_MAPSIZE - 1 || ( sp.y > 0 && gridy == 0 ) ) {
6922 submaps_with_active_items.erase( { abs.x + gridx, abs.y + gridy, gridz } );
6923 }
6924 if( gridx + sp.x >= 0 && gridy + sp.y < my_MAPSIZE ) {
6925 copy_grid( tripoint( gridx, gridy, gridz ),
6926 tripoint( gridx + sp.x, gridy + sp.y, gridz ) );
6927 update_vehicle_list( get_submap_at_grid( { gridx, gridy, gridz } ), gridz );
6928 } else {
6929 loadn( tripoint( gridx, gridy, gridz ), true );
6930 }
6931 }
6932 } else { // sy < 0; work through it backwards
6933 for( int gridy = my_MAPSIZE - 1; gridy >= 0; gridy-- ) {
6934 if( gridx == my_MAPSIZE - 1 || gridy == my_MAPSIZE - 1 ) {
6935 submaps_with_active_items.erase( { abs.x + gridx, abs.y + gridy, gridz } );
6936 }
6937 if( gridx + sp.x >= 0 && gridy + sp.y >= 0 ) {
6938 copy_grid( tripoint( gridx, gridy, gridz ),
6939 tripoint( gridx + sp.x, gridy + sp.y, gridz ) );
6940 update_vehicle_list( get_submap_at_grid( { gridx, gridy, gridz } ), gridz );
6941 } else {
6942 loadn( tripoint( gridx, gridy, gridz ), true );
6943 }
6944 }
6945 }
6946 }
6947 }
6948 }
6949 if( zlevels ) {
6950 //Go through the generated maps and fill in the roofs
6951 for( int gridz = zmin; gridz <= zmax; gridz++ ) {
6952 if( sp.x > 0 ) {
6953 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6954 add_roofs( {my_MAPSIZE - 1, gridy, gridz} );
6955 }
6956 } else if( sp.x < 0 ) {
6957 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6958 add_roofs( {0, gridy, gridz} );
6959 }
6960 }
6961
6962 if( sp.y > 0 ) {
6963 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
6964 add_roofs( {gridx, my_MAPSIZE - 1, gridz} );
6965 }
6966 } else if( sp.y < 0 ) {
6967 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
6968 add_roofs( {gridx, 0, gridz} );
6969 }
6970 }
6971 }
6972 }
6973
6975
6976 g->setremoteveh( remoteveh );
6977
6978 if( !support_cache_dirty.empty() ) {
6979 shift_tripoint_set( support_cache_dirty, shift_offset_pt, boundaries_2d );
6980 }
6981}
void copy_grid(const tripoint &to, const tripoint &from)
Definition: map.cpp:7582
void shift_traps(const tripoint &shift)
As part of the map shifting, this shifts the trap locations stored in traplocs.
Definition: map.cpp:6708
template void shift_bitset_cache< MAPSIZE_X, SEEX >(std::bitset< MAPSIZE_X *MAPSIZE_X > &cache, point s)
static void shift_tripoint_set(std::set< tripoint > &set, point offset, const half_open_rectangle< point > &boundaries)
Definition: map.cpp:6767
template void shift_bitset_cache< MAPSIZE, 1 >(std::bitset< MAPSIZE *MAPSIZE > &cache, point s)
int remoteveh(player *, item *, bool, const tripoint &)
Definition: iuse.cpp:8260

References add_roofs(), clear_vehicle_cache(), clear_vehicle_list(), copy_grid(), debugmsg, g, get_abs_sub(), get_cache(), get_submap_at_grid(), loadn(), MAPSIZE_X, MAPSIZE_Y, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, point_zero, iuse::remoteveh(), reset_vehicle_cache(), SEEX, SEEY, set_abs_sub(), shift_bitset_cache< MAPSIZE, 1 >(), shift_bitset_cache< MAPSIZE_X, SEEX >(), shift_traps(), shift_tripoint_set(), submaps_with_active_items, support_cache_dirty, update_vehicle_list(), point::x, point::y, and zlevels.

Referenced by shift_traps(), and game::update_map().

◆ shift_traps()

void map::shift_traps ( const tripoint shift)
protected

As part of the map shifting, this shifts the trap locations stored in traplocs.

Parameters
shiftThe amount shifting in submap, the same as go into shift.

Definition at line 6708 of file map.cpp.

6709{
6710 // Offset needs to have sign opposite to shift direction
6711 const tripoint offset( -shift.x * SEEX, -shift.y * SEEY, -shift.z );
6712 for( auto iter = field_furn_locs.begin(); iter != field_furn_locs.end(); ) {
6713 tripoint &pos = *iter;
6714 pos += offset;
6715 if( inbounds( pos ) ) {
6716 ++iter;
6717 } else {
6718 iter = field_furn_locs.erase( iter );
6719 }
6720 }
6721 for( auto &traps : traplocs ) {
6722 for( auto iter = traps.begin(); iter != traps.end(); ) {
6723 tripoint &pos = *iter;
6724 pos += offset;
6725 if( inbounds( pos ) ) {
6726 ++iter;
6727 } else {
6728 // Theoretical enhancement: if this is not the last entry of the vector,
6729 // move the last entry into pos and remove the last entry instead of iter.
6730 // This would avoid moving all the remaining entries.
6731 iter = traps.erase( iter );
6732 }
6733 }
6734 }
6735}
void shift(point s)
Shift the map along the vector s.
Definition: map.cpp:6840

References field_furn_locs, inbounds(), SEEX, SEEY, shift(), and traplocs.

Referenced by shift().

◆ shift_vehicle_z()

void map::shift_vehicle_z ( vehicle veh,
int  z_shift 
)

Definition at line 6794 of file map.cpp.

6795{
6796
6797 tripoint src = veh.global_pos3();
6798 tripoint dst = src + tripoint_above * z_shift;
6799
6800 submap *src_submap = get_submap_at( src );
6801 submap *dst_submap = get_submap_at( dst );
6802
6803 int our_i = -1;
6804 for( size_t i = 0; i < src_submap->vehicles.size(); i++ ) {
6805 if( src_submap->vehicles[i].get() == &veh ) {
6806 our_i = i;
6807 break;
6808 }
6809 }
6810
6811 if( our_i == -1 ) {
6812 debugmsg( "shift_vehicle [%s] failed could not find vehicle", veh.name );
6813 return;
6814 }
6815
6816 for( auto &prt : veh.get_all_parts() ) {
6817 prt.part().precalc[0].z -= z_shift;
6818 }
6819
6820 veh.set_submap_moved( tripoint( dst.x / SEEX, dst.y / SEEY, dst.z ) );
6821 auto src_submap_veh_it = src_submap->vehicles.begin() + our_i;
6822 dst_submap->vehicles.push_back( std::move( *src_submap_veh_it ) );
6823 src_submap->vehicles.erase( src_submap_veh_it );
6824 dst_submap->is_uniform = false;
6826
6827 update_vehicle_list( dst_submap, dst.z );
6828
6829 level_cache &ch = get_cache( src.z );
6830 for( const vehicle *elem : ch.vehicle_list ) {
6831 if( elem == &veh ) {
6832 ch.vehicle_list.erase( &veh );
6833 ch.zone_vehicles.erase( &veh );
6834 break;
6835 }
6836 }
6837
6838}

References debugmsg, vehicle::get_all_parts(), get_cache(), get_submap_at(), vehicle::global_pos3(), invalidate_max_populated_zlev(), submap::is_uniform, avatar_action::move(), vehicle::name, SEEX, SEEY, vehicle::set_submap_moved(), tripoint_above, update_vehicle_list(), level_cache::vehicle_list, submap::vehicles, tripoint::x, tripoint::y, tripoint::z, and level_cache::zone_vehicles.

Referenced by vehicle::shift_zlevel().

◆ shoot()

void map::shoot ( const tripoint p,
projectile proj,
bool  hit_items 
)

Definition at line 3783 of file map.cpp.

3784{
3785 float initial_damage = 0.0;
3786 for( const damage_unit &dam : proj.impact ) {
3787 initial_damage += dam.amount * dam.damage_multiplier;
3788 initial_damage += dam.res_pen;
3789 }
3790 if( initial_damage < 0 ) {
3791 return;
3792 }
3793
3794 float dam = initial_damage;
3795
3796 if( has_flag( "ALARMED", p ) && !g->timed_events.queued( TIMED_EVENT_WANTED ) ) {
3797 sounds::sound( p, 30, sounds::sound_t::alarm, _( "an alarm sound!" ), true, "environment",
3798 "alarm" );
3799 const tripoint abs = ms_to_sm_copy( getabs( p ) );
3800 g->timed_events.add( TIMED_EVENT_WANTED, calendar::turn + 30_minutes, 0, abs );
3801 }
3802
3803 const bool inc = proj.has_effect( ammo_effect_INCENDIARY ) ||
3804 proj.impact.type_damage( DT_HEAT ) > 0;
3805 if( const optional_vpart_position vp = veh_at( p ) ) {
3806 dam = vp->vehicle().damage( vp->part_index(), dam, inc ? DT_HEAT : DT_STAB, hit_items );
3807 }
3808
3809 ter_id terrain = ter( p );
3810 ter_t ter = terrain.obj();
3811
3812 if( ter.bash.ranged ) {
3813 const ranged_bash_info &ri = *ter.bash.ranged;
3814 if( !hit_items && !check( ri.block_unaimed_chance ) ) {
3815 // Nothing, it's a miss
3816 } else if( ri.reduction_laser && proj.has_effect( ammo_effect_LASER ) ) {
3817 dam -= rng( ri.reduction_laser->min, ri.reduction_laser->max );
3818 } else {
3819 dam -= rng( ri.reduction.min, ri.reduction.max );
3820 if( dam > ri.destroy_threshold ) {
3821 bash_params params{0, false, true, hit_items, 1.0, false};
3822 bash_ter_success( p, params );
3823 }
3824 if( dam <= 0 && is_transparent( p ) && get_avatar().sees( p ) ) {
3825 add_msg( _( "The shot is stopped by the %s!" ), tername( p ) );
3826 }
3827 if( ri.flammable && inc ) {
3828 add_field( p, fd_fire, 1 );
3829 }
3830 }
3831 } else if( impassable( p ) && !is_transparent( p ) ) {
3832 bash( p, dam, false );
3833 // TODO: Preserve some residual damage when it makes sense.
3834 dam = 0;
3835 }
3836
3837 for( const ammo_effect_str_id &ae_id : proj.get_ammo_effects() ) {
3838 const ammo_effect &ae = *ae_id;
3839 if( ae.trail_field_type ) {
3840 if( x_in_y( ae.trail_chance, 100 ) ) {
3842 }
3843 }
3844 }
3845
3846 dam = std::max( 0.0f, dam );
3847
3848 // Check fields?
3849 const field_entry *fieldhit = get_field( p, fd_web );
3850 if( fieldhit != nullptr ) {
3851 if( inc ) {
3852 add_field( p, fd_fire, fieldhit->get_field_intensity() - 1 );
3853 } else if( dam > 5 + fieldhit->get_field_intensity() * 5 &&
3854 one_in( 5 - fieldhit->get_field_intensity() ) ) {
3855 dam -= rng( 1, 2 + fieldhit->get_field_intensity() * 2 );
3856 remove_field( p, fd_web );
3857 }
3858 }
3859
3860 // Rescale the damage
3861 if( dam <= 0 ) {
3862 proj.impact.damage_units.clear();
3863 return;
3864 } else if( dam < initial_damage ) {
3865 proj.impact.mult_damage( dam / static_cast<double>( initial_damage ) );
3866 }
3867
3868 //Projectiles with NO_ITEM_DAMAGE flag won't damage items at all
3869 if( !hit_items || !inbounds( p ) ) {
3870 return;
3871 }
3872
3873 // Make sure the message is sensible for the ammo effects. Lasers aren't projectiles.
3874 std::string damage_message;
3875 if( proj.has_effect( ammo_effect_LASER ) ) {
3876 damage_message = _( "laser beam" );
3877 } else if( proj.has_effect( ammo_effect_LIGHTNING ) ) {
3878 damage_message = _( "bolt of electricity" );
3879 } else if( proj.has_effect( ammo_effect_PLASMA ) ) {
3880 damage_message = _( "bolt of plasma" );
3881 } else {
3882 damage_message = _( "flying projectile" );
3883 }
3884
3885 smash_items( p, dam, damage_message, false );
3886}
@ DT_STAB
Definition: damage.h:27
static const ammo_effect_str_id ammo_effect_LIGHTNING("LIGHTNING")
static const ammo_effect_str_id ammo_effect_LASER("LASER")
static const ammo_effect_str_id ammo_effect_INCENDIARY("INCENDIARY")
static const ammo_effect_str_id ammo_effect_PLASMA("PLASMA")
int check(unformattable)
Definition: fmtlib_core.h:1610
int trail_chance
Definition: ammo_effect.h:45
int trail_intensity_max
Definition: ammo_effect.h:44
int trail_intensity_min
Definition: ammo_effect.h:43
field_type_id trail_field_type
Definition: ammo_effect.h:40
std::vector< damage_unit > damage_units
Definition: damage.h:52
float type_damage(damage_type dt) const
Definition: damage.cpp:64
void mult_damage(double multiplier, bool pre_armor=false)
Definition: damage.cpp:48
float amount
Definition: damage.h:37
float damage_multiplier
Definition: damage.h:40
float res_pen
Definition: damage.h:38
const std::set< ammo_effect_str_id > & get_ammo_effects()
Definition: projectile.h:42
damage_instance impact
Definition: projectile.h:21
bool has_effect(const ammo_effect_str_id &id) const
Definition: projectile.h:55
bool flammable
Definition: mapdata.h:40
numeric_interval< int > reduction
Definition: mapdata.h:36
cata::optional< numeric_interval< int > > reduction_laser
Definition: mapdata.h:38
int destroy_threshold
Definition: mapdata.h:39
units::probability block_unaimed_chance
Definition: mapdata.h:41

References _, add_field(), add_msg(), sounds::alarm, ammo_effect_INCENDIARY, ammo_effect_LASER, ammo_effect_LIGHTNING, ammo_effect_PLASMA, damage_unit::amount, bash(), bash_ter_success(), ranged_bash_info::block_unaimed_chance, detail::check(), damage_unit::damage_multiplier, damage_instance::damage_units, ranged_bash_info::destroy_threshold, DT_HEAT, DT_STAB, fd_fire, fd_web, ranged_bash_info::flammable, g, projectile::get_ammo_effects(), get_avatar(), get_field(), field_entry::get_field_intensity(), getabs(), projectile::has_effect(), has_flag(), projectile::impact, impassable(), inbounds(), is_transparent(), ms_to_sm_copy(), damage_instance::mult_damage(), one_in(), ranged_bash_info::reduction, ranged_bash_info::reduction_laser, remove_field(), damage_unit::res_pen, rng(), sees(), smash_items(), sounds::sound(), ter(), tername(), terrain, TIMED_EVENT_WANTED, ammo_effect::trail_chance, ammo_effect::trail_field_type, ammo_effect::trail_intensity_max, ammo_effect::trail_intensity_min, calendar::turn, damage_instance::type_damage(), veh_at(), and x_in_y().

Referenced by ranged::execute_shaped_attack(), and projectile_attack().

◆ smash_items()

void map::smash_items ( const tripoint p,
int  power,
const std::string &  cause_message,
bool  do_destroy 
)

Tries to smash the items at the given tripoint.

Definition at line 3052 of file map.cpp.

3054{
3055 if( !has_items( p ) ) {
3056 return;
3057 }
3058
3059 // Keep track of how many items have been damaged, and what the first one is
3060 int items_damaged = 0;
3061 int items_destroyed = 0;
3062 std::string damaged_item_name;
3063
3064 // TODO: Bullets should be pretty much corpse-only
3065 constexpr const int min_destroy_threshold = 50;
3066
3067 std::vector<item> contents;
3068 map_stack items = i_at( p );
3069 for( auto i = items.begin(); i != items.end(); ) {
3070 // If the power is low or it's not an explosion, only pulp rezing corpses
3071 if( ( power < min_destroy_threshold || !do_destroy ) && !i->can_revive() ) {
3072 i++;
3073 continue;
3074 }
3075
3076 // Active explosives arbitrarily get double the destroy threshold
3077 bool is_active_explosive = i->active && i->type->get_use( "explosion" ) != nullptr;
3078 if( is_active_explosive && i->charges == 0 ) {
3079 i++;
3080 continue;
3081 }
3082
3083 const float material_factor = i->chip_resistance( true );
3084 // Intact non-rezing get a boost
3085 const float intact_mult = 2.0f -
3086 ( static_cast<float>( i->damage_level( i->max_damage() ) ) / i->max_damage() );
3087 const float destroy_threshold = min_destroy_threshold
3088 + material_factor * intact_mult
3089 + ( is_active_explosive ? min_destroy_threshold : 0 );
3090 // For pulping, only consider material resistance. Non-rezing can only be destroyed.
3091 const float pulp_threshold = i->can_revive() ? material_factor : destroy_threshold;
3092 // Active explosives that will explode this turn are indestructible (they are exploding "now")
3093 if( power < pulp_threshold ) {
3094 i++;
3095 continue;
3096 }
3097
3098 bool item_was_destroyed = false;
3099 float destroy_chance = ( power - pulp_threshold ) / 4.0;
3100
3101 const bool by_charges = i->count_by_charges();
3102 if( by_charges ) {
3103 destroy_chance *= i->charges_per_volume( 250_ml );
3104 if( x_in_y( destroy_chance, destroy_threshold ) ) {
3105 item_was_destroyed = true;
3106 }
3107 } else {
3108 const field_type_id type_blood = i->is_corpse() ? i->get_mtype()->bloodType() : fd_null;
3109 float roll = rng_float( 0.0, destroy_chance );
3110 if( roll >= destroy_threshold ) {
3111 item_was_destroyed = true;
3112 } else if( roll >= pulp_threshold ) {
3113 // Only pulp
3114 i->set_damage( i->max_damage() );
3115 // TODO: Blood streak cone away from explosion
3116 add_splash( type_blood, p, 1, destroy_chance );
3117 // If it was the first item to be damaged, note it
3118 if( items_damaged == 0 ) {
3119 damaged_item_name = i->tname();
3120 }
3121 items_damaged++;
3122 }
3123 }
3124
3125 // Remove them if they were damaged too much
3126 if( item_was_destroyed ) {
3127 // But save the contents, except for irremovable gunmods
3128 for( item *elem : i->contents.all_items_top() ) {
3129 if( !elem->is_irremovable() ) {
3130 contents.push_back( item( *elem ) );
3131 }
3132 }
3133
3134 if( items_damaged == 0 ) {
3135 damaged_item_name = i->tname();
3136 }
3137 i = i_rem( p, i );
3138 items_damaged++;
3139 items_destroyed++;
3140 } else {
3141 i++;
3142 }
3143 }
3144
3145 // Let the player know that the item was damaged if they can see it.
3146 if( items_destroyed > 1 && g->u.sees( p ) ) {
3147 add_msg( m_bad, _( "The %s destroys several items!" ), cause_message );
3148 } else if( items_destroyed == 1 && items_damaged == 1 && g->u.sees( p ) ) {
3149 //~ %1$s: the cause of destruction, %2$s: destroyed item name
3150 add_msg( m_bad, _( "The %1$s destroys the %2$s!" ), cause_message, damaged_item_name );
3151 } else if( items_damaged > 1 && g->u.sees( p ) ) {
3152 add_msg( m_bad, _( "The %s damages several items." ), cause_message );
3153 } else if( items_damaged == 1 && g->u.sees( p ) ) {
3154 //~ %1$s: the cause of damage, %2$s: damaged item name
3155 add_msg( m_bad, _( "The %1$s damages the %2$s." ), cause_message, damaged_item_name );
3156 }
3157
3158 for( const item &it : contents ) {
3159 add_item_or_charges( p, it );
3160 }
3161}
void add_splash(const field_type_id &type, const tripoint &center, int radius, int intensity)
Definition: map.cpp:5601

References _, add_item_or_charges(), add_msg(), add_splash(), item_contents::all_items_top(), item_stack::begin(), item::contents, item_stack::end(), fd_null, g, has_items(), i_at(), i_rem(), m_bad, rng_float(), and x_in_y().

Referenced by explosion_handler::do_blast(), explosion_handler::do_blast_new(), move_vehicle(), and shoot().

◆ spawn_an_item() [1/2]

item & map::spawn_an_item ( const tripoint p,
item  new_item,
int  charges,
int  damlevel 
)

Definition at line 4204 of file map.cpp.

4206{
4207 if( charges && new_item.charges > 0 ) {
4208 //let's fail silently if we specify charges for an item that doesn't support it
4209 new_item.charges = charges;
4210 }
4211 new_item = new_item.in_its_container();
4212 if( ( new_item.made_of( LIQUID ) && has_flag( "SWIMMABLE", p ) ) ||
4213 has_flag( "DESTROY_ITEM", p ) ) {
4214 return null_item_reference();
4215 }
4216
4217 new_item.set_damage( damlevel );
4218
4219 return add_item_or_charges( p, new_item );
4220}
item & set_damage(int qty)
Filter setting damage constrained by min_damage and max_damage.
Definition: item.cpp:714
item in_its_container() const
Returns this item into its default container.
Definition: item.cpp:841

References add_item_or_charges(), item::charges, has_flag(), item::in_its_container(), LIQUID, item::made_of(), null_item_reference(), and item::set_damage().

Referenced by salvage_actor::cut_up(), spawn_an_item(), and spawn_item().

◆ spawn_an_item() [2/2]

void map::spawn_an_item ( point  p,
item  new_item,
int  charges,
int  damlevel 
)
inline

Definition at line 1249 of file map.h.

1249 {
1250 spawn_an_item( tripoint( p, abs_sub.z ), new_item, charges, damlevel );
1251 }
item & spawn_an_item(const tripoint &p, item new_item, int charges, int damlevel)
Definition: map.cpp:4204

References abs_sub, spawn_an_item(), and tripoint::z.

◆ spawn_artifact()

void map::spawn_artifact ( const tripoint p)

Definition at line 4243 of file map.cpp.

4244{
4246}
itype_id new_artifact()
Definition: artifact.cpp:677

References add_item_or_charges(), new_artifact(), and calendar::start_of_cataclysm.

Referenced by draw_mine(), and draw_temple().

◆ spawn_item() [1/4]

void map::spawn_item ( const tripoint p,
const itype_id type_id,
unsigned  quantity = 1,
int  charges = 0,
const time_point birthday = calendar::start_of_cataclysm,
int  damlevel = 0 
)

Definition at line 4253 of file map.cpp.

4256{
4257 if( type_id.is_null() ) {
4258 return;
4259 }
4260
4261 if( item_is_blacklisted( type_id ) ) {
4262 return;
4263 }
4264 // recurse to spawn (quantity - 1) items
4265 for( size_t i = 1; i < quantity; i++ ) {
4266 spawn_item( p, type_id, 1, charges, birthday, damlevel );
4267 }
4268 // spawn the item
4269 item new_item( type_id, birthday );
4270 if( one_in( 3 ) && new_item.has_flag( "VARSIZE" ) ) {
4271 new_item.set_flag( "FIT" );
4272 }
4273
4274 spawn_an_item( p, new_item, charges, damlevel );
4275}
bool is_null() const
Returns whether this represents the id of the null-object (in which case it's the null-id).
Definition: string_id.h:317
bool item_is_blacklisted(const itype_id &id)

References item::has_flag(), string_id< T >::is_null(), item_is_blacklisted(), one_in(), item::set_flag(), spawn_an_item(), and spawn_item().

Referenced by computer_session::action_extract_rad_source(), jmapgen_spawn_item::apply(), MapExtras::burned_ground_parser(), talk_function::buy_100_logs(), talk_function::buy_10_logs(), activity_handlers::chop_planks_finish(), create_anomaly(), create_burnproducts(), iexamine::curtains(), vehicle::damage_direct(), monexamine::deactivate_pet(), MapExtras::dead_vegetation_parser(), game::disable_robot(), construct::done_window_curtains(), draw_lab(), draw_mine(), draw_office_tower(), explosion_handler::emp_blast(), iexamine::fertilize_plant(), dig_activity_actor::finish(), iexamine::flower_marloss(), activity_handlers::hacksaw_finish(), vehicle::handle_trap(), make_rubble(), mapgen_cavern(), mapgen_tutorial(), MapExtras::mx_casings(), MapExtras::mx_drugdeal(), MapExtras::mx_grave(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), MapExtras::mx_roadworks(), om_cutdown_trees(), trap::on_disarmed(), activity_handlers::oxytorch_finish(), pick_plant(), mission_start::place_deposit_box(), MapExtras::place_fumarole(), mission_start::place_priest_diary(), place_vending(), activity_handlers::pry_nails_finish(), mission_start::ranch_nurse_1(), mission_start::ranch_nurse_2(), mission_start::ranch_scavenger_1(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), iexamine::recycle_compactor(), iexamine::shrub_marloss(), sinkhole_safety_roll(), spawn_item(), Character::suffer_from_other_mutations(), iexamine::tree_hickory(), iexamine::tree_marloss(), try_remove_bear_trap(), try_remove_heavysnare(), try_remove_lightsnare(), unroll_digging(), and game::vertical_move().

◆ spawn_item() [2/4]

void map::spawn_item ( const tripoint p,
const std::string &  type_id,
unsigned  quantity = 1,
int  charges = 0,
const time_point birthday = calendar::start_of_cataclysm,
int  damlevel = 0 
)
inline

Definition at line 1210 of file map.h.

1212 {
1213 spawn_item( p, itype_id( type_id ), quantity, charges, birthday, damlevel );
1214 }

References itype_id, and spawn_item().

◆ spawn_item() [3/4]

void map::spawn_item ( point  p,
const itype_id type_id,
unsigned  quantity = 1,
int  charges = 0,
const time_point birthday = calendar::start_of_cataclysm,
int  damlevel = 0 
)
inline

Definition at line 1202 of file map.h.

1204 {
1205 spawn_item( tripoint( p, abs_sub.z ), type_id, quantity, charges, birthday, damlevel );
1206 }

References abs_sub, spawn_item(), and tripoint::z.

◆ spawn_item() [4/4]

void map::spawn_item ( point  p,
const std::string &  type_id,
unsigned  quantity = 1,
int  charges = 0,
const time_point birthday = calendar::start_of_cataclysm,
int  damlevel = 0 
)
inline

Definition at line 1215 of file map.h.

1217 {
1218 spawn_item( tripoint( p, abs_sub.z ), type_id, quantity, charges, birthday, damlevel );
1219 }

References abs_sub, spawn_item(), and tripoint::z.

◆ spawn_items() [1/2]

std::vector< item * > map::spawn_items ( const tripoint p,
const std::vector< item > &  new_items 
)

Definition at line 4222 of file map.cpp.

4223{
4224 std::vector<item *> ret;
4225 if( !inbounds( p ) || has_flag( "DESTROY_ITEM", p ) ) {
4226 return ret;
4227 }
4228 const bool swimmable = has_flag( "SWIMMABLE", p );
4229 for( const item &new_item : new_items ) {
4230
4231 if( new_item.made_of( LIQUID ) && swimmable ) {
4232 continue;
4233 }
4234 item &it = add_item_or_charges( p, new_item );
4235 if( !it.is_null() ) {
4236 ret.push_back( &it );
4237 }
4238 }
4239
4240 return ret;
4241}
bool is_null() const
Definition: item.cpp:732

References add_item_or_charges(), has_flag(), inbounds(), item::is_null(), LIQUID, and cata::hash64_detail::ret.

Referenced by jmapgen_loot::apply(), bash_furn_success(), bash_items(), bash_ter_success(), complete_construction(), construct::done_deconstruct(), dig_activity_actor::finish(), dig_channel_activity_actor::finish(), talk_function::loot_building(), MapExtras::mx_casings(), MapExtras::mx_corpses(), process_fields_in_submap(), put_items_from_loc(), veh_utils::repair_part(), smash(), and spawn_items().

◆ spawn_items() [2/2]

void map::spawn_items ( point  p,
const std::vector< item > &  new_items 
)
inline

Definition at line 1325 of file map.h.

1325 {
1326 spawn_items( tripoint( p, abs_sub.z ), new_items );
1327 }

References abs_sub, spawn_items(), and tripoint::z.

◆ spawn_monsters()

void map::spawn_monsters ( bool  ignore_sight)

Spawn monsters from submap spawn points and from the overmap.

Parameters
ignore_sightIf true, monsters may spawn in the view of the player character (useful when the whole map has been loaded instead, e.g. when starting a new game, or after teleportation or after moving vertically). If false, monsters are not spawned in view of player character.

Definition at line 7780 of file map.cpp.

7781{
7782 const int zmin = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
7783 const int zmax = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
7784 tripoint gp;
7785 int &gx = gp.x;
7786 int &gy = gp.y;
7787 int &gz = gp.z;
7788 for( gz = zmin; gz <= zmax; gz++ ) {
7789 for( gx = 0; gx < my_MAPSIZE; gx++ ) {
7790 for( gy = 0; gy < my_MAPSIZE; gy++ ) {
7791 spawn_monsters_submap( gp, ignore_sight );
7792 }
7793 }
7794 }
7795}
void spawn_monsters_submap(const tripoint &gp, bool ignore_sight)
Definition: map.cpp:7725

References abs_sub, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, spawn_monsters_submap(), tripoint::x, tripoint::y, tripoint::z, and zlevels.

Referenced by game::do_turn(), editmap::mapgen_preview(), game::place_player_overmap(), game::start_game(), game::update_map(), and game::vertical_shift().

◆ spawn_monsters_submap()

void map::spawn_monsters_submap ( const tripoint gp,
bool  ignore_sight 
)
private

Definition at line 7725 of file map.cpp.

7726{
7727 // Load unloaded monsters
7728 // TODO: fix point types
7730
7731 // Only spawn new monsters after existing monsters are loaded.
7732 // TODO: fix point types
7733 auto groups = overmap_buffer.groups_at( tripoint_abs_sm( gp + abs_sub.xy() ) );
7734 for( auto &mgp : groups ) {
7735 spawn_monsters_submap_group( gp, *mgp, ignore_sight );
7736 }
7737
7738 submap *const current_submap = get_submap_at_grid( gp );
7739 const tripoint gp_ms = sm_to_ms_copy( gp );
7740
7741 for( auto &i : current_submap->spawns ) {
7742 const tripoint center = gp_ms + i.pos;
7744
7745 for( int j = 0; j < i.count; j++ ) {
7746 monster tmp( i.type );
7747 tmp.mission_id = i.mission_id;
7748 if( i.name != "NONE" ) {
7749 tmp.unique_name = i.name;
7750 }
7751 if( i.friendly ) {
7752 tmp.friendly = -1;
7753 }
7754
7755 const auto valid_location = [&]( const tripoint & p ) {
7756 // Checking for creatures via g is only meaningful if this is the main game map.
7757 // If it's some local map instance, the coordinates will most likely not even match.
7758 return ( !g || &get_map() != this || !g->critter_at( p ) ) && tmp.can_move_to( p );
7759 };
7760
7761 const auto place_it = [&]( const tripoint & p ) {
7762 monster *const placed = g->place_critter_at( make_shared_fast<monster>( tmp ), p );
7763 if( placed ) {
7764 placed->on_load();
7765 }
7766 };
7767
7768 // First check out defined spawn location for a valid placement, and if that doesn't work
7769 // then fall back to picking a random point that is a valid location.
7770 if( valid_location( center ) ) {
7771 place_it( center );
7772 } else if( const cata::optional<tripoint> pos = random_point( points, valid_location ) ) {
7773 place_it( *pos );
7774 }
7775 }
7776 }
7777 current_submap->spawns.clear();
7778}
void spawn_monsters_submap_group(const tripoint &gp, mongroup &group, bool ignore_sight)
Definition: map.cpp:7591
void on_load()
Retroactively update monster.
Definition: monster.cpp:3013
std::vector< mongroup * > groups_at(const tripoint_abs_sm &p)
Monster groups at p - absolute submap coordinates.
void spawn_monster(const tripoint_abs_sm &p)
Spawn monsters from the overmap onto the main map (game::m).

References abs_sub, monster::can_move_to(), center, monster::friendly, g, get_map(), get_submap_at_grid(), overmapbuffer::groups_at(), monster::mission_id, monster::on_load(), overmap_buffer, points_in_radius(), random_point(), sm_to_ms_copy(), overmapbuffer::spawn_monster(), spawn_monsters_submap_group(), submap::spawns, monster::unique_name, and tripoint::xy().

Referenced by spawn_monsters().

◆ spawn_monsters_submap_group()

void map::spawn_monsters_submap_group ( const tripoint gp,
mongroup group,
bool  ignore_sight 
)
private

Definition at line 7591 of file map.cpp.

7592{
7593 const int s_range = std::min( HALF_MAPSIZE_X,
7594 g->u.sight_range( g->light_level( g->u.posz() ) ) );
7595 int pop = group.population;
7596 std::vector<tripoint> locations;
7597 if( !ignore_sight ) {
7598 // If the submap is one of the outermost submaps, assume that monsters are
7599 // invisible there.
7600 if( gp.x == 0 || gp.y == 0 || gp.x + 1 == MAPSIZE || gp.y + 1 == MAPSIZE ) {
7601 ignore_sight = true;
7602 }
7603 }
7604
7605 if( gp.z != g->u.posz() ) {
7606 // Note: this is only OK because 3D vision isn't a thing yet
7607 ignore_sight = true;
7608 }
7609
7610 static const auto allow_on_terrain = [&]( const tripoint & p ) {
7611 // TODO: flying creatures should be allowed to spawn without a floor,
7612 // but the new creature is created *after* determining the terrain, so
7613 // we can't check for it here.
7614 return passable( p ) && has_floor( p );
7615 };
7616
7617 // If the submap is uniform, we can skip many checks
7618 const submap *current_submap = get_submap_at_grid( gp );
7619 bool ignore_terrain_checks = false;
7620 bool ignore_inside_checks = gp.z < 0;
7621 if( current_submap->is_uniform ) {
7622 const tripoint upper_left{ SEEX * gp.x, SEEY * gp.y, gp.z };
7623 if( !allow_on_terrain( upper_left ) ||
7624 ( !ignore_inside_checks && has_flag_ter_or_furn( TFLAG_INDOORS, upper_left ) ) ) {
7625 const tripoint glp = getabs( gp );
7626 dbg( DL::Warn ) << "Empty locations for group " << group.type.str()
7627 << " at uniform submap " << gp << " global " << glp;
7628 return;
7629 }
7630
7631 ignore_terrain_checks = true;
7632 ignore_inside_checks = true;
7633 }
7634
7635 for( int x = 0; x < SEEX; ++x ) {
7636 for( int y = 0; y < SEEY; ++y ) {
7637 int fx = x + SEEX * gp.x;
7638 int fy = y + SEEY * gp.y;
7639 tripoint fp{ fx, fy, gp.z };
7640 if( g->critter_at( fp ) != nullptr ) {
7641 continue; // there is already some creature
7642 }
7643
7644 if( !ignore_terrain_checks && !allow_on_terrain( fp ) ) {
7645 continue; // solid area, impassable
7646 }
7647
7648 if( !ignore_sight && sees( g->u.pos(), fp, s_range ) ) {
7649 continue; // monster must spawn outside the viewing range of the player
7650 }
7651
7652 if( !ignore_inside_checks && has_flag_ter_or_furn( TFLAG_INDOORS, fp ) ) {
7653 continue; // monster must spawn outside.
7654 }
7655
7656 locations.push_back( fp );
7657 }
7658 }
7659
7660 if( locations.empty() ) {
7661 // TODO: what now? there is no possible place to spawn monsters, most
7662 // likely because the player can see all the places.
7663 const tripoint glp = getabs( gp );
7664 dbg( DL::Warn ) << "Empty locations for group " << group.type.str()
7665 << " at " << gp << " global " << glp;
7666 // Just kill the group. It's not like we're removing existing monsters
7667 // Unless it's a horde - then don't kill it and let it spawn behind a tree or smoke cloud
7668 if( !group.horde ) {
7669 group.clear();
7670 }
7671
7672 return;
7673 }
7674
7675 if( pop ) {
7676 // Populate the group from its population variable.
7677 for( int m = 0; m < pop; m++ ) {
7679 if( !spawn_details.name ) {
7680 continue;
7681 }
7682 monster tmp( spawn_details.name );
7683
7684 // If a monster came from a horde population, configure them to always be willing to rejoin a horde.
7685 if( group.horde ) {
7686 tmp.set_horde_attraction( MHA_ALWAYS );
7687 }
7688 for( int i = 0; i < spawn_details.pack_size; i++ ) {
7689 group.monsters.push_back( tmp );
7690 }
7691 }
7692 }
7693
7694 // Find horde's target submap
7695 // TODO: fix point types
7696 tripoint horde_target( tripoint( -abs_sub.xy(), abs_sub.z ) + group.target.xy().raw() );
7697 sm_to_ms( horde_target );
7698 for( auto &tmp : group.monsters ) {
7699 for( int tries = 0; tries < 10 && !locations.empty(); tries++ ) {
7701 if( !tmp.can_move_to( p ) ) {
7702 continue; // target can not contain the monster
7703 }
7704 if( group.horde ) {
7705 // Give monster a random point near horde's expected destination
7706 const tripoint rand_dest = horde_target +
7707 point( rng( 0, SEEX ), rng( 0, SEEY ) );
7708 const int turns = rl_dist( p, rand_dest ) + group.interest;
7709 tmp.wander_to( rand_dest, turns );
7710 add_msg( m_debug, "%s targeting %d,%d,%d", tmp.disp_name(),
7711 tmp.wander_pos.x, tmp.wander_pos.y, tmp.wander_pos.z );
7712 }
7713
7714 monster *const placed = g->place_critter_at( make_shared_fast<monster>( tmp ), p );
7715 if( placed ) {
7716 placed->on_load();
7717 }
7718 break;
7719 }
7720 }
7721 // indicates the group is empty, and can be removed later
7722 group.clear();
7723}
void sm_to_ms(int &x, int &y)
static constexpr int HALF_MAPSIZE_X
@ MHA_ALWAYS
Definition: monster.h:76
generic_factory< overmap_location > locations("overmap location")

References abs_sub, add_msg(), dbg, g, get_submap_at_grid(), getabs(), MonsterGroupManager::GetResultFromGroup(), HALF_MAPSIZE_X, has_flag_ter_or_furn(), has_floor(), submap::is_uniform, anonymous_namespace{overmap_location.cpp}::locations, m_debug, MAPSIZE, MHA_ALWAYS, MonsterGroupResult::name, monster::on_load(), MonsterGroupResult::pack_size, passable(), random_entry_removed(), rl_dist(), rng(), sees(), SEEX, SEEY, monster::set_horde_attraction(), sm_to_ms(), TFLAG_INDOORS, Warn, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by spawn_monsters_submap().

◆ spawn_natural_artifact()

void map::spawn_natural_artifact ( const tripoint p,
artifact_natural_property  prop 
)

Definition at line 4248 of file map.cpp.

4249{
4251}
itype_id new_natural_artifact(artifact_natural_property prop)
Definition: artifact.cpp:931

References add_item_or_charges(), new_natural_artifact(), and calendar::start_of_cataclysm.

Referenced by debug_menu::debug(), and MapExtras::mx_portal_in().

◆ spread_gas()

void map::spread_gas ( field_entry cur,
const tripoint p,
int  percent_spread,
const time_duration outdoor_age_speedup,
scent_block sblk 
)
private

Definition at line 251 of file map_field.cpp.

253{
254 map &here = get_map();
255 // TODO: fix point types
256 const oter_id &cur_om_ter =
258 const bool sheltered = g->is_sheltered( p );
260 const int winddirection = weather.winddirection;
261 const int windpower = get_local_windpower( weather.windspeed, cur_om_ter, p, winddirection,
262 sheltered );
263
264 const int current_intensity = cur.get_field_intensity();
265 const field_type_id ft_id = cur.get_field_type();
266
267 const int scent_neutralize = ft_id->get_intensity_level( current_intensity -
269
270 if( scent_neutralize > 0 ) {
271 // modify scents by neutralization value (minus)
272 for( const tripoint &tmp : points_in_radius( p, 1 ) ) {
273 sblk.apply_gas( tmp, scent_neutralize );
274 }
275 }
276
277 // Dissipate faster outdoors.
278 if( is_outside( p ) ) {
279 const time_duration current_age = cur.get_field_age();
280 cur.set_field_age( current_age + outdoor_age_speedup );
281 }
282
283 // Bail out if we don't meet the spread chance or required intensity.
284 if( current_intensity <= 1 || rng( 1, 100 - windpower ) > percent_spread ) {
285 return;
286 }
287
288 // First check if we can fall
289 // TODO: Make fall and rise chances parameters to enable heavy/light gas
290 if( zlevels && p.z > -OVERMAP_DEPTH ) {
291 const tripoint down{ p.xy(), p.z - 1 };
292 if( gas_can_spread_to( cur, p, down ) && valid_move( p, down, true, true ) ) {
293 maptile down_tile = maptile_at_internal( down );
294 gas_spread_to( cur, down_tile, down );
295 return;
296 }
297 }
298
299 auto neighs = get_neighbors( p );
300 size_t end_it = static_cast<size_t>( rng( 0, neighs.size() - 1 ) );
301 std::vector<size_t> spread;
302 std::vector<size_t> neighbour_vec;
303 // Then, spread to a nearby point.
304 // If not possible (or randomly), try to spread up
305 // Wind direction will block the field spreading into the wind.
306 // Start at end_it + 1, then wrap around until all elements have been processed.
307 for( size_t i = ( end_it + 1 ) % neighs.size(), count = 0;
308 count != neighs.size();
309 i = ( i + 1 ) % neighs.size(), count++ ) {
310 const auto &neigh = neighs[i];
311 if( gas_can_spread_to( cur, p, neigh.first ) ) {
312 spread.push_back( i );
313 }
314 }
315 auto maptiles = get_wind_blockers( winddirection, p );
316 // Three map tiles that are facing the wind direction.
317 const maptile remove_tile = std::get<0>( maptiles );
318 const maptile remove_tile2 = std::get<1>( maptiles );
319 const maptile remove_tile3 = std::get<2>( maptiles );
320 if( !spread.empty() && ( !zlevels || one_in( spread.size() ) ) ) {
321 // Construct the destination from offset and p
322 if( g->is_sheltered( p ) || windpower < 5 ) {
323 std::pair<tripoint, maptile> &n = neighs[ random_entry( spread ) ];
324 gas_spread_to( cur, n.second, n.first );
325 } else {
326 end_it = static_cast<size_t>( rng( 0, neighs.size() - 1 ) );
327 // Start at end_it + 1, then wrap around until all elements have been processed.
328 for( size_t i = ( end_it + 1 ) % neighs.size(), count = 0;
329 count != neighs.size();
330 i = ( i + 1 ) % neighs.size(), count++ ) {
331 const auto &neigh = neighs[i].second;
332 if( ( neigh.pos_.x != remove_tile.pos_.x && neigh.pos_.y != remove_tile.pos_.y ) ||
333 ( neigh.pos_.x != remove_tile2.pos_.x && neigh.pos_.y != remove_tile2.pos_.y ) ||
334 ( neigh.pos_.x != remove_tile3.pos_.x && neigh.pos_.y != remove_tile3.pos_.y ) ) {
335 neighbour_vec.push_back( i );
336 } else if( x_in_y( 1, std::max( 2, windpower ) ) ) {
337 neighbour_vec.push_back( i );
338 }
339 }
340 if( !neighbour_vec.empty() ) {
341 std::pair<tripoint, maptile> &n = neighs[neighbour_vec[rng( 0, neighbour_vec.size() - 1 )]];
342 gas_spread_to( cur, n.second, n.first );
343 }
344 }
345 } else if( zlevels && p.z < OVERMAP_HEIGHT ) {
346 const tripoint up{ p.xy(), p.z + 1 };
347 if( gas_can_spread_to( cur, p, up ) && valid_move( p, up, true, true ) ) {
348 maptile up_tile = maptile_at_internal( up );
349 gas_spread_to( cur, up_tile, up );
350 }
351 }
352}
std::tuple< maptile, maptile, maptile > get_wind_blockers(const int &winddirection, const tripoint &pos)
Definition: map_field.cpp:1894
bool gas_can_spread_to(field_entry &cur, const tripoint &src, const tripoint &dst)
Definition: map_field.cpp:211
void gas_spread_to(field_entry &cur, maptile &dst, const tripoint &p)
Definition: map_field.cpp:225
coords::coord_point< tripoint, coords::origin::abs, coords::omt > tripoint_abs_omt
Definition: coordinates.h:493
double get_local_windpower(double windpower, const oter_id &omter, const tripoint &location, const int &winddirection, bool sheltered)
Definition: weather.cpp:938
const field_intensity_level & get_intensity_level(int level=0) const
Definition: field_type.cpp:130
point pos_
Definition: submap.h:243
void apply_gas(const tripoint &p, const int nintensity=0)
Definition: scent_block.cpp:45

References scent_block::apply_gas(), detail::count(), g, gas_can_spread_to(), gas_spread_to(), field_entry::get_field_age(), field_entry::get_field_intensity(), field_entry::get_field_type(), field_type::get_intensity_level(), get_local_windpower(), get_map(), get_neighbors(), get_weather(), get_wind_blockers(), getabs(), is_outside(), maptile_at_internal(), ms_to_omt_copy(), one_in(), overmap_buffer, OVERMAP_DEPTH, OVERMAP_HEIGHT, points_in_radius(), maptile::pos_, random_entry(), rng(), field_intensity_level::scent_neutralization, field_entry::set_field_age(), overmapbuffer::ter(), valid_move(), point::x, x_in_y(), tripoint::xy(), point::y, tripoint::z, and zlevels.

Referenced by process_fields_in_submap().

◆ stored_volume()

units::volume map::stored_volume ( const tripoint p)

Definition at line 4283 of file map.cpp.

4284{
4285 return i_at( p ).stored_volume();
4286}
units::volume stored_volume() const
Total volume of the items here.
Definition: item_stack.cpp:98

References i_at(), and item_stack::stored_volume().

◆ support_dirty()

void map::support_dirty ( const tripoint p)
private

Definition at line 2325 of file map.cpp.

2326{
2327 if( zlevels ) {
2328 support_cache_dirty.insert( p );
2329 }
2330}

References support_cache_dirty, and zlevels.

Referenced by add_field(), add_item_or_charges(), drop_furniture(), furn_set(), ter_set(), and update_suspension_cache().

◆ supports_above()

bool map::supports_above ( const tripoint p) const

Does this tile support vehicles and furniture above it.

Definition at line 2078 of file map.cpp.

2079{
2080 const maptile tile = maptile_at( p );
2081 const ter_t &ter = tile.get_ter_t();
2082 if( ter.movecost == 0 ) {
2083 return true;
2084 }
2085
2086 const furn_id frn_id = tile.get_furn();
2087 if( frn_id != f_null ) {
2088 const furn_t &frn = frn_id.obj();
2089 if( frn.movecost < 0 ) {
2090 return true;
2091 }
2092 }
2093
2094 return veh_at( p ).has_value();
2095}
constexpr bool has_value() const noexcept
Definition: optional.h:123
furn_id get_furn() const
Definition: submap.h:256

References f_null, maptile::get_furn(), maptile::get_ter_t(), cata::optional< T >::has_value(), maptile_at(), map_data_common_t::movecost, int_id< T >::obj(), ter(), and veh_at().

Referenced by vehicle::check_falling_or_floating(), and drop_furniture().

◆ ter() [1/2]

ter_id map::ter ( const tripoint p) const

Definition at line 1556 of file map.cpp.

1557{
1558 if( !inbounds( p ) ) {
1559 return t_null;
1560 }
1561
1562 point l;
1563 submap *const current_submap = get_submap_at( p, l );
1564
1565 return current_submap->get_ter( l );
1566}

References get_submap_at(), submap::get_ter(), inbounds(), and t_null.

Referenced by computer_session::action_conveyor(), computer_session::action_data_anal(), computer_session::action_deactivate_shock_vent(), computer_session::action_elevator_on(), computer_session::action_extract_rad_source(), computer_session::action_geiger(), computer_session::action_irradiator(), computer_session::action_sample(), computer_session::action_srcf_elevator(), computer_session::action_srcf_seal(), actualize(), ter_furn_transform::add_all_messages(), add_boardable(), apply< ter_t >(), cata_event_dispatch::avatar_moves(), bash_rating(), bash_resistance(), bash_strength(), bash_ter_furn(), bash_ter_success(), board_up(), MapExtras::burned_ground_parser(), activity_handlers::burrow_finish(), can_construct(), can_do_activity_there(), can_examine_at(), iexamine::cardreader(), iexamine::cardreader_foodplace(), construct::check_deconstruct(), vehicle::autodrive_controller::check_drivable(), vehicle::check_heli_ascend(), activity_handlers::chop_logs_finish(), chop_tree_activity(), activity_handlers::chop_tree_finish(), close_door(), complete_construction(), coverage(), iexamine::curtains(), MapExtras::dead_vegetation_parser(), determine_wall_corner(), displace_water(), construct::done_deconstruct(), construct::done_digormine_stair(), construct::done_extract_maybe_revert_to_dirt(), construct::done_mine_upstair(), editmap_hilight::draw(), draw_connections(), draw_lab(), editmap::draw_main_ui_overlay(), draw_mine(), draw_temple(), draw_triffid(), avatar_action::eat_here(), explosion_handler::emp_blast(), examine(), game::examine(), game::extended_description(), computer_session::failure_destroy_data(), computer_session::failure_pump_explode(), computer_session::failure_pump_leak(), feature< ter_id >(), talk_function::field_plant(), activity_handlers::fill_liquid_do_turn(), activity_handlers::fill_pit_finish(), find_base_construction(), game::find_or_make_stairs(), find_potential_computer_point(), dig_activity_actor::finish(), dig_channel_activity_actor::finish(), hacking_activity_actor::finish(), Character::floor_bedding_warmth(), fromPumpFuel(), iexamine::fswitch(), gas_can_spread_to(), generic_multi_activity_locations(), get_changed_ids_from_update(), get_hack_type(), get_harvest(), get_harvest_names(), get_known_connections(), get_roof(), get_ter_transforms_into(), iexamine::getGasPumpByNumber(), iexamine::getNearFilledGasTank(), getNearPumpCount(), activity_handlers::hacksaw_finish(), has_flag_ter(), has_neighbor(), has_pre_terrain(), hit_with_acid(), advanced_inv_area::init(), is_bashable(), is_bashable_ter(), anonymous_namespace{gates.cpp}::gate_data::is_suitable_wall(), is_suspension_valid(), iexamine::ledge(), talk_function::loot_building(), mapgen_ants_generic(), mapgen_lake_shore(), fungal_effects::marlossify(), map_stack::max_volume(), map_funcs::migo_nerve_cage_removal(), avatar_action::move(), move_cost(), move_vehicle(), MapExtras::mx_grove(), MapExtras::mx_helicopter(), MapExtras::mx_house_spider(), MapExtras::mx_house_wasp(), MapExtras::mx_portal_in(), MapExtras::mx_shrubbery(), iexamine::nanofab(), obstacle_coverage(), om_cutdown_trees(), om_harvest_ter(), open(), open_door(), activity_handlers::oxytorch_finish(), iexamine::pedestal_wyrm(), tutorial_game::per_turn(), activity_handlers::pickaxe_finish(), iexamine::pit(), iexamine::pit_covered(), mission_start::place_deposit_box(), place_items(), game::place_player(), game::print_fields_info(), game::print_graffiti_info(), game::print_terrain_info(), process_fields_in_submap(), produce_sap(), activity_handlers::pry_nails_finish(), rad_scorch(), resolve_regional_terrain_and_furniture(), restock_fruits(), mission_start::reveal_lab_train_depot(), shoot(), supports_above(), temperature_flag_at_point(), rot::temperature_flag_for_location(), ter(), tername(), gates::toggle_gate(), iexamine::toPumpFuel(), ter_furn_transform::transform(), translate(), translate_radius(), trap_set(), avatar_funcs::try_to_sleep(), turnOnSelectedPump(), Character::update_bodytemp(), update_suspension_cache(), editmap::update_view_with_help(), pick_lock_actor::use(), vehicle_wheel_traction(), game::vertical_move(), game::walk_move(), and water_from().

◆ ter() [2/2]

ter_id map::ter ( point  p) const
inline

Definition at line 815 of file map.h.

815 {
816 return ter( tripoint( p, abs_sub.z ) );
817 }

References abs_sub, ter(), and tripoint::z.

◆ ter_set() [1/2]

bool map::ter_set ( const tripoint p,
const ter_id new_terrain 
)

Definition at line 1697 of file map.cpp.

1698{
1699 if( !inbounds( p ) ) {
1700 return false;
1701 }
1702
1703 point l;
1704 submap *const current_submap = get_submap_at( p, l );
1705 const ter_id old_id = current_submap->get_ter( l );
1706 if( old_id == new_terrain ) {
1707 // Nothing changed
1708 return false;
1709 }
1710
1711 current_submap->set_ter( l, new_terrain );
1712
1713 // Set the dirty flags
1714 const ter_t &old_t = old_id.obj();
1715 const ter_t &new_t = new_terrain.obj();
1716
1717 // HACK: Hack around ledges in traplocs or else it gets NASTY in z-level mode
1718 if( old_t.trap != tr_null && old_t.trap != tr_ledge ) {
1719 auto &traps = traplocs[old_t.trap.to_i()];
1720 const auto iter = std::find( traps.begin(), traps.end(), p );
1721 if( iter != traps.end() ) {
1722 traps.erase( iter );
1723 }
1724 }
1725 if( new_t.trap != tr_null && new_t.trap != tr_ledge ) {
1726 traplocs[new_t.trap.to_i()].push_back( p );
1727 }
1728
1729 if( old_t.transparent != new_t.transparent ) {
1732 }
1733
1734 if( old_t.has_flag( TFLAG_INDOORS ) != new_t.has_flag( TFLAG_INDOORS ) ) {
1736 }
1737
1738 if( new_t.has_flag( TFLAG_NO_FLOOR ) != old_t.has_flag( TFLAG_NO_FLOOR ) ) {
1740 // It's a set, not a flag
1741 support_cache_dirty.insert( p );
1743 }
1744
1745 if( new_t.has_flag( TFLAG_SUSPENDED ) != old_t.has_flag( TFLAG_SUSPENDED ) ) {
1747 if( new_t.has_flag( TFLAG_SUSPENDED ) ) {
1748 level_cache &ch = get_cache( p.z );
1749 ch.suspension_cache.emplace_back( getabs( p ).xy() );
1750 }
1751 }
1752
1754
1756
1757 // TODO: Limit to changes that affect move cost, traps and stairs
1759
1760 tripoint above( p.xy(), p.z + 1 );
1761 // Make sure that if we supported something and no longer do so, it falls down
1762 support_dirty( above );
1763
1764 return true;
1765}
std::list< point > suspension_cache
Definition: map.h:312
trap_id trap
Definition: mapdata.h:473

References detail::find(), get_cache(), get_submap_at(), submap::get_ter(), getabs(), map_data_common_t::has_flag(), inbounds(), invalidate_max_populated_zlev(), int_id< T >::obj(), set_floor_cache_dirty(), set_memory_seen_cache_dirty(), set_outside_cache_dirty(), set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_suspension_cache_dirty(), submap::set_ter(), set_transparency_cache_dirty(), support_cache_dirty, support_dirty(), level_cache::suspension_cache, TFLAG_INDOORS, TFLAG_NO_FLOOR, TFLAG_SUSPENDED, int_id< T >::to_i(), tr_ledge, tr_null, map_data_common_t::transparent, ter_t::trap, traplocs, tripoint::xy(), and tripoint::z.

Referenced by computer_session::action_elevator_on(), computer_session::action_srcf_elevator(), add_computer(), jmapgen_terrain::apply(), jmapgen_computer::apply(), jmapgen_setmap::apply(), apply< ter_t >(), bash_ter_success(), board_up(), MapExtras::burned_ground_parser(), iexamine::cardreader(), iexamine::cardreader_foodplace(), iexamine::cardreader_robofac(), activity_handlers::chop_logs_finish(), activity_handlers::chop_tree_finish(), activity_handlers::churn_finish(), close_door(), collapse_at(), collapse_invalid_suspension(), complete_construction(), iexamine::curtains(), MapExtras::dead_vegetation_parser(), displace_water(), construct::done_deconstruct(), construct::done_digormine_stair(), construct::done_extract_maybe_revert_to_dirt(), construct::done_mine_upstair(), construct::done_ramp_high(), construct::done_ramp_low(), construct::done_wood_stairs(), draw_anthill(), draw_circle_ter(), draw_connections(), draw_lab(), draw_line_ter(), draw_mine(), draw_rough_circle_ter(), draw_slimepit(), draw_square_ter(), draw_temple(), draw_triffid(), avatar_action::eat_here(), explosion_handler::emp_blast(), computer_session::failure_pump_leak(), computer_session::failure_shutdown(), farm_action(), talk_function::field_harvest(), activity_handlers::fill_pit_finish(), dig_activity_actor::finish(), dig_channel_activity_actor::finish(), hacking_activity_actor::finish(), activity_handlers::forage_finish(), game::forced_door_closing(), mapgen_function_json_base::formatted_set_incredibly_simple(), mapf::formatted_set_simple(), fromPumpFuel(), iexamine::fswitch(), activity_handlers::hacksaw_finish(), iexamine::harvest_plant(), iexamine::harvest_ter(), iexamine::harvest_ter_nectar(), hit_with_acid(), talk_function::loot_building(), make_rubble(), mapgen_ants_curved(), mapgen_ants_four_way(), mapgen_ants_generic(), mapgen_ants_straight(), mapgen_ants_tee(), mapgen_cavern(), mapgen_crater(), mapgen_field(), mapgen_forest_trail_curved(), mapgen_forest_trail_four_way(), mapgen_forest_trail_straight(), mapgen_forest_trail_tee(), mapgen_hellmouth(), mapgen_highway(), mapgen_hive(), mapgen_lake_shore(), mapgen_null(), mapgen_parking_lot(), mapgen_rift(), mapgen_river_curved(), mapgen_river_curved_not(), mapgen_river_straight(), mapgen_road(), mapgen_rock_partial(), mapgen_sewer_curved(), mapgen_sewer_four_way(), mapgen_sewer_straight(), mapgen_sewer_tee(), mapgen_test(), mapgen_tutorial(), fungal_effects::marlossify(), map_funcs::migo_nerve_cage_removal(), move_vehicle(), MapExtras::mx_bandits_block(), MapExtras::mx_clay_deposit(), MapExtras::mx_clearcut(), MapExtras::mx_grave(), MapExtras::mx_grove(), MapExtras::mx_helicopter(), MapExtras::mx_house_wasp(), MapExtras::mx_pond(), MapExtras::mx_portal_in(), MapExtras::mx_roadblock(), MapExtras::mx_shrubbery(), MapExtras::mx_spider(), om_cutdown_trees(), om_harvest_ter(), om_set_hide_site(), open_door(), activity_handlers::oxytorch_finish(), iexamine::pedestal_temple(), iexamine::pedestal_wyrm(), pick_plant(), iexamine::pit(), iexamine::pit_covered(), MapExtras::place_fumarole(), place_gas_pump(), mission_start::place_npc_software(), process_fields_in_submap(), activity_handlers::pry_nails_finish(), rad_scorch(), mission_start::ranch_nurse_4(), mission_start::ranch_nurse_5(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), resolve_regional_terrain_and_furniture(), restock_fruits(), science_room(), set(), iexamine::shrub_marloss(), fungal_effects::spread_fungus_one_tile(), ter_or_furn_set(), ter_set(), gates::toggle_gate(), iexamine::toPumpFuel(), ter_furn_transform::transform(), translate(), translate_radius(), iexamine::tree_hickory(), iexamine::tree_maple(), iexamine::tree_maple_tapped(), iexamine::tree_marloss(), turnOnSelectedPump(), and game::vertical_move().

◆ ter_set() [2/2]

bool map::ter_set ( point  p,
const ter_id new_terrain 
)
inline

Definition at line 840 of file map.h.

840 {
841 return ter_set( tripoint( p, abs_sub.z ), new_terrain );
842 }

References abs_sub, ter_set(), and tripoint::z.

◆ tername() [1/2]

◆ tername() [2/2]

std::string map::tername ( point  p) const
inline

Definition at line 845 of file map.h.

845 {
846 return tername( tripoint( p, abs_sub.z ) );
847 }

References abs_sub, tername(), and tripoint::z.

◆ tinder_at()

bool map::tinder_at ( const tripoint p)

Checks if there are any tinder flagged items on the tile.

Parameters
ptile to check

Definition at line 2684 of file map.cpp.

2685{
2686 for( const auto &i : i_at( p ) ) {
2687 if( i.has_flag( "TINDER" ) ) {
2688 return true;
2689 }
2690 }
2691 return false;
2692}

References i_at().

Referenced by activity_handlers::start_fire_do_turn().

◆ tr_at()

const trap & map::tr_at ( const tripoint p) const

Definition at line 5198 of file map.cpp.

5199{
5200 if( !inbounds( p ) ) {
5201 return tr_null.obj();
5202 }
5203
5204 point l;
5205 submap *const current_submap = get_submap_at( p, l );
5206
5207 if( current_submap->get_ter( l ).obj().trap != tr_null ) {
5208 return current_submap->get_ter( l ).obj().trap.obj();
5209 }
5210
5211 return current_submap->get_trap( l ).obj();
5212}

References get_submap_at(), submap::get_ter(), submap::get_trap(), inbounds(), int_id< T >::obj(), tr_null, and ter_t::trap.

Referenced by can_see_trap_at(), construct::check_empty(), construct::check_no_trap(), complete_construction(), construction_activity(), creature_on_trap(), disarm_trap(), draw_lab(), editmap::draw_main_ui_overlay(), drop_or_embed_projectile(), game::examine(), feature< trap_id >(), fill_funnels(), game::fling_creature(), Character::floor_bedding_warmth(), get_convection_temperature(), game::get_dangerous_tile(), game::grabbed_furn_move(), vehicle::handle_trap(), advanced_inv_area::init(), place_trap_actor::is_allowed(), trapfunc::map_regen(), MapExtras::mx_minefield(), MapExtras::mx_portal(), character_funcs::pick_safe_adjacent_tile(), place_and_add_as_known(), place_construction(), tutorial_game::post_action(), game::print_trap_info(), game::process_artifact(), relic_funcs::process_recharge_entry(), game::prompt_dangerous_tile(), iexamine::rubble(), character_funcs::search_surroundings(), iexamine::shrub_wildveggies(), sinkhole_safety_roll(), iexamine::trap(), avatar_funcs::try_to_sleep(), editmap::update_view_with_help(), and valid_move().

◆ translate()

void map::translate ( const ter_id from,
const ter_id to 
)

Definition at line 3992 of file map.cpp.

3993{
3994 if( from == to ) {
3995 debugmsg( "map::translate %s => %s",
3996 from.obj().name(),
3997 from.obj().name() );
3998 return;
3999 }
4000 for( const tripoint &p : points_on_zlevel() ) {
4001 if( ter( p ) == from ) {
4002 ter_set( p, to );
4003 }
4004 }
4005}

References debugmsg, map_data_common_t::name(), int_id< T >::obj(), points_on_zlevel(), ter(), and ter_set().

Referenced by jmapgen_translate::apply(), mapgen_lake_shore(), start_location::prepare_map(), mission_start::ranch_nurse_5(), mission_start::ranch_nurse_6(), mission_start::ranch_nurse_7(), mission_start::ranch_nurse_8(), and mission_start::ranch_scavenger_3().

◆ translate_radius()

void map::translate_radius ( const ter_id from,
const ter_id to,
float  radi,
const tripoint p,
bool  same_submap = false,
bool  toggle_between = false 
)

Definition at line 4008 of file map.cpp.

4010{
4011 if( from == to ) {
4012 debugmsg( "map::translate %s => %s", from.obj().name(), to.obj().name() );
4013 return;
4014 }
4015
4016 const tripoint abs_omt_p = ms_to_omt_copy( getabs( p ) );
4017 for( const tripoint &t : points_on_zlevel() ) {
4018 const tripoint abs_omt_t = ms_to_omt_copy( getabs( t ) );
4019 const float radiX = trig_dist( p, t );
4020 if( ter( t ) == from ) {
4021 // within distance, and either no submap limitation or same overmap coords.
4022 if( radiX <= radi && ( !same_submap || abs_omt_t == abs_omt_p ) ) {
4023 ter_set( t, to );
4024 }
4025 } else if( toggle_between && ter( t ) == to ) {
4026 if( radiX <= radi && ( !same_submap || abs_omt_t == abs_omt_p ) ) {
4027 ter_set( t, from );
4028 }
4029 }
4030 }
4031}

References debugmsg, getabs(), ms_to_omt_copy(), map_data_common_t::name(), int_id< T >::obj(), points_on_zlevel(), ter(), ter_set(), and trig_dist().

Referenced by computer_session::action_extract_rad_source(), computer_session::action_irradiator(), computer_session::action_lock(), computer_session::action_open(), computer_session::action_release(), computer_session::action_release_bionics(), computer_session::action_shutters(), and computer_session::action_unlock().

◆ trap_locations()

const std::vector< tripoint > & map::trap_locations ( const trap_id type) const

Definition at line 7826 of file map.cpp.

7827{
7828 return traplocs[type.to_i()];
7829}

References traplocs, and type.

◆ trap_set()

void map::trap_set ( const tripoint p,
const trap_id type 
)

Definition at line 5250 of file map.cpp.

5251{
5252 if( !inbounds( p ) ) {
5253 return;
5254 }
5255
5256 point l;
5257 submap *const current_submap = get_submap_at( p, l );
5258 const ter_t &ter = current_submap->get_ter( l ).obj();
5259 if( ter.trap != tr_null ) {
5260 debugmsg( "set trap %s on top of terrain %s which already has a builit-in trap",
5261 type.obj().name(), ter.name() );
5262 return;
5263 }
5264
5265 // If there was already a trap here, remove it.
5266 if( current_submap->get_trap( l ) != tr_null ) {
5267 remove_trap( p );
5268 }
5269
5270 current_submap->set_trap( l, type );
5271 if( type != tr_null ) {
5272 traplocs[type.to_i()].push_back( p );
5273 }
5274}
void remove_trap(const tripoint &p)
Definition: map.cpp:5334

References debugmsg, get_submap_at(), submap::get_ter(), submap::get_trap(), inbounds(), int_id< T >::obj(), remove_trap(), submap::set_trap(), ter(), tr_null, traplocs, and type.

Referenced by jmapgen_trap::apply(), apply< trap >(), construction_activity(), construct::done_mark_firewood(), construct::done_mark_practice_target(), draw_lab(), vehicle::handle_trap(), mtrap_set(), MapExtras::mx_portal(), place_and_add_as_known(), place_construction(), and explosion_handler::explosion_funcs::resonance_cascade().

◆ unboard_vehicle() [1/2]

void map::unboard_vehicle ( const tripoint p,
bool  dead_passenger = false 
)

Definition at line 1159 of file map.cpp.

1160{
1162 player *passenger = nullptr;
1163 if( !vp ) {
1164 debugmsg( "map::unboard_vehicle: vehicle not found" );
1165 // Try and force unboard the player anyway.
1166 passenger = g->critter_at<player>( p );
1167 if( passenger ) {
1168 passenger->in_vehicle = false;
1169 passenger->controlling_vehicle = false;
1170 }
1171 return;
1172 }
1173 passenger = vp->get_passenger();
1174 unboard_vehicle( *vp, passenger, dead_passenger );
1175}
bool controlling_vehicle
Definition: character.h:246

References Character::controlling_vehicle, debugmsg, g, Character::in_vehicle, optional_vpart_position::part_with_feature(), unboard_vehicle(), veh_at(), and VPFLAG_BOARDABLE.

◆ unboard_vehicle() [2/2]

void map::unboard_vehicle ( const vpart_reference vp,
Character passenger,
bool  dead_passenger = false 
)

Definition at line 1139 of file map.cpp.

1140{
1141 // Mark the part as un-occupied regardless of whether there's a live passenger here.
1143 vp.vehicle().invalidate_mass();
1144
1145 if( !passenger ) {
1146 if( !dead_passenger ) {
1147 debugmsg( "map::unboard_vehicle: passenger not found" );
1148 }
1149 return;
1150 }
1151 passenger->in_vehicle = false;
1152 // Only make vehicle go out of control if the driver is the one unboarding.
1153 if( passenger->controlling_vehicle ) {
1154 vp.vehicle().skidding = true;
1155 }
1156 passenger->controlling_vehicle = false;
1157}
void invalidate_mass()
Mark mass caches and pivot cache as dirty.
Definition: vehicle.cpp:6972
vehicle_part & part() const
Yields the vehicle_part object referenced by this.
Definition: vehicle.cpp:6775
::vehicle & vehicle() const

References Character::controlling_vehicle, debugmsg, Character::in_vehicle, vehicle::invalidate_mass(), vpart_reference::part(), vehicle_part::passenger_flag, vehicle_part::remove_flag(), vehicle::skidding, and vpart_reference::vehicle().

Referenced by board_vehicle(), iexamine::chainfence(), detach_vehicle(), game::fling_creature(), talk_function::individual_mission(), game::is_game_over(), npc::move_to(), game::moving_vehicle_dismount(), game::phasing_move(), game::place_player(), game::place_player_overmap(), mattack::ranged_pull(), shake_vehicle(), game::swap_critters(), avatar_action::swim(), unboard_vehicle(), and game::vertical_move().

◆ update_lum()

void map::update_lum ( item_location loc,
bool  add 
)

Update luminosity before and after item's transformation.

Definition at line 4506 of file map.cpp.

4507{
4508 item *target = loc.get_item();
4509
4510 // if the item is not emissive, do nothing
4511 if( !target->is_emissive() ) {
4512 return;
4513 }
4514
4515 point l;
4516 submap *const current_submap = get_submap_at( loc.position(), l );
4517
4518 if( add ) {
4519 current_submap->update_lum_add( l, *target );
4520 } else {
4521 current_submap->update_lum_rem( l, *target );
4522 }
4523}
bool is_emissive() const
Whether the item emits any light at all.
Definition: item.cpp:6943

References om_direction::add(), item_location::get_item(), get_submap_at(), item::is_emissive(), item_location::position(), submap::update_lum_add(), and submap::update_lum_rem().

Referenced by update_lum().

◆ update_pathfinding_cache()

void map::update_pathfinding_cache ( int  zlev) const

Definition at line 8921 of file map.cpp.

8922{
8923 auto &cache = get_pathfinding_cache( zlev );
8924 if( !cache.dirty ) {
8925 return;
8926 }
8927
8928 std::uninitialized_fill_n( &cache.special[0][0], MAPSIZE_X * MAPSIZE_Y, PF_NORMAL );
8929
8930 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
8931 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
8932 const auto cur_submap = get_submap_at_grid( { smx, smy, zlev } );
8933 if( !cur_submap ) {
8934 return;
8935 }
8936
8937 tripoint p( 0, 0, zlev );
8938
8939 for( int sx = 0; sx < SEEX; ++sx ) {
8940 p.x = sx + smx * SEEX;
8941 for( int sy = 0; sy < SEEY; ++sy ) {
8942 p.y = sy + smy * SEEY;
8943
8944 pf_special cur_value = PF_NORMAL;
8945
8946 maptile tile( cur_submap, point( sx, sy ) );
8947
8948 const auto &terrain = tile.get_ter_t();
8949 const auto &furniture = tile.get_furn_t();
8950 int part;
8951 const vehicle *veh = veh_at_internal( p, part );
8952
8953 const int cost = move_cost_internal( furniture, terrain, veh, part );
8954
8955 if( cost > 2 ) {
8956 cur_value |= PF_SLOW;
8957 } else if( cost <= 0 ) {
8958 cur_value |= PF_WALL;
8959 if( terrain.has_flag( TFLAG_CLIMBABLE ) ) {
8960 cur_value |= PF_CLIMBABLE;
8961 }
8962 }
8963
8964 if( veh != nullptr ) {
8965 cur_value |= PF_VEHICLE;
8966 }
8967
8968 for( const auto &fld : tile.get_field() ) {
8969 const field_entry &cur = fld.second;
8970 const field_type_id type = cur.get_field_type();
8971 const int field_intensity = cur.get_field_intensity();
8972 if( type.obj().get_dangerous( field_intensity - 1 ) ) {
8973 cur_value |= PF_FIELD;
8974 }
8975 }
8976
8977 if( !tile.get_trap_t().is_benign() || !terrain.trap.obj().is_benign() ) {
8978 cur_value |= PF_TRAP;
8979 }
8980
8981 if( terrain.has_flag( TFLAG_GOES_DOWN ) || terrain.has_flag( TFLAG_GOES_UP ) ||
8982 terrain.has_flag( TFLAG_RAMP ) || terrain.has_flag( TFLAG_RAMP_UP ) ||
8983 terrain.has_flag( TFLAG_RAMP_DOWN ) ) {
8984 cur_value |= PF_UPDOWN;
8985 }
8986
8987 if( terrain.has_flag( TFLAG_SHARP ) ) {
8988 cur_value |= PF_SHARP;
8989 }
8990
8991 cache.special[p.x][p.y] = cur_value;
8992 }
8993 }
8994 }
8995 }
8996
8997 cache.dirty = false;
8998}
@ TFLAG_CLIMBABLE
Definition: mapdata.h:307
@ TFLAG_SHARP
Definition: mapdata.h:296
pf_special
Definition: pathfinding.h:7
@ PF_NORMAL
Definition: pathfinding.h:8
@ PF_FIELD
Definition: pathfinding.h:12

References furniture, maptile::get_field(), field_entry::get_field_intensity(), field_entry::get_field_type(), maptile::get_furn_t(), get_pathfinding_cache(), get_submap_at_grid(), maptile::get_ter_t(), maptile::get_trap_t(), trap::is_benign(), MAPSIZE_X, MAPSIZE_Y, move_cost_internal(), my_MAPSIZE, PF_CLIMBABLE, PF_FIELD, PF_NORMAL, PF_SHARP, PF_SLOW, PF_TRAP, PF_UPDOWN, PF_VEHICLE, PF_WALL, SEEX, SEEY, sx, sy, terrain, TFLAG_CLIMBABLE, TFLAG_GOES_DOWN, TFLAG_GOES_UP, TFLAG_RAMP, TFLAG_RAMP_DOWN, TFLAG_RAMP_UP, TFLAG_SHARP, type, veh_at_internal(), tripoint::x, and tripoint::y.

Referenced by get_pathfinding_cache_ref().

◆ update_submap_active_item_status()

void map::update_submap_active_item_status ( const tripoint p)

Definition at line 5660 of file map.cpp.

5661{
5662 point l;
5663 submap *const current_submap = get_submap_at( p, l );
5664 if( current_submap->active_items.empty() ) {
5665 submaps_with_active_items.erase( tripoint( abs_sub.x + p.x / SEEX, abs_sub.y + p.y / SEEY, p.z ) );
5666 }
5667}

References abs_sub, submap::active_items, active_item_cache::empty(), get_submap_at(), SEEX, SEEY, submaps_with_active_items, tripoint::x, tripoint::y, and tripoint::z.

◆ update_suspension_cache()

void map::update_suspension_cache ( const int &  z)

Definition at line 8133 of file map.cpp.

8134{
8135 level_cache &ch = get_cache( z );
8136 if( !ch.suspension_cache_dirty ) {
8137 return;
8138 }
8139 std::list<point> &suspension_cache = ch.suspension_cache;
8141 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
8142 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
8143 const submap *cur_submap = get_submap_at_grid( { smx, smy, z } );
8144
8145 if( cur_submap == nullptr ) {
8146 debugmsg( "Tried to run suspension check at (%d,%d,%d) but the submap is not loaded", smx, smy,
8147 z );
8148 continue;
8149 }
8150
8151 for( int sx = 0; sx < SEEX; ++sx ) {
8152 for( int sy = 0; sy < SEEY; ++sy ) {
8153 point sp( sx, sy );
8154 const ter_t &terrain = cur_submap->get_ter( sp ).obj();
8155 if( terrain.has_flag( TFLAG_SUSPENDED ) ) {
8156 tripoint loc( coords::project_combine( point_om_sm( point( smx, smy ) ), point_sm_ms( sp ) ).raw(),
8157 z );
8158 suspension_cache.emplace_back( getabs( loc ).xy() );
8159 }
8160 }
8161 }
8162 }
8163 }
8165 }
8166
8167 for( auto iter = suspension_cache.begin(); iter != suspension_cache.end(); ) {
8168 const point absp = *iter;
8169 const point locp = getlocal( absp );
8170 const tripoint loctp( locp, z );
8171 if( !inbounds( locp ) ) {
8172 ++iter;
8173 continue;
8174 }
8175 const submap *cur_submap = get_submap_at( loctp );
8176 if( cur_submap == nullptr ) {
8177 debugmsg( "Tried to run suspension check at (%d,%d,%d) but the submap is not loaded", locp.x,
8178 locp.y, z );
8179 ++iter;
8180 continue;
8181 }
8182 const ter_t &terrain = ter( locp ).obj();
8183 if( terrain.has_flag( TFLAG_SUSPENDED ) ) {
8184 if( !is_suspension_valid( loctp ) ) {
8185 support_dirty( loctp );
8186 iter = suspension_cache.erase( iter );
8187 } else {
8188 ++iter;
8189 }
8190 } else {
8191 iter = suspension_cache.erase( iter );
8192 }
8193 }
8194 ch.suspension_cache_dirty = false;
8195}
coords::coord_point< point, coords::origin::overmap, coords::sm > point_om_sm
Definition: coordinates.h:477
auto project_combine(const coord_point< PointL, CoarseOrigin, CoarseScale > &coarse, const coord_point< PointR, FineOrigin, FineScale > &fine)
Definition: coordinates.h:413
bool suspension_cache_initialized
Definition: map.h:310

References debugmsg, get_cache(), get_submap_at(), get_submap_at_grid(), submap::get_ter(), getabs(), getlocal(), inbounds(), is_suspension_valid(), my_MAPSIZE, int_id< T >::obj(), coords::project_combine(), SEEX, SEEY, support_dirty(), level_cache::suspension_cache, level_cache::suspension_cache_dirty, level_cache::suspension_cache_initialized, sx, sy, ter(), terrain, TFLAG_SUSPENDED, point::x, and point::y.

Referenced by build_map_cache().

◆ update_vehicle_cache()

void map::update_vehicle_cache ( vehicle ,
int  old_zlevel 
)

◆ update_vehicle_list()

void map::update_vehicle_list ( const submap to,
int  zlev 
)

Definition at line 398 of file map.cpp.

399{
400 // Update vehicle data
401 level_cache &ch = get_cache( zlev );
402 for( const auto &elem : to->vehicles ) {
403 ch.vehicle_list.insert( elem.get() );
404 if( !elem->loot_zones.empty() ) {
405 ch.zone_vehicles.insert( elem.get() );
406 }
407 }
408
410}

References get_cache(), last_full_vehicle_list_dirty, level_cache::vehicle_list, submap::vehicles, and level_cache::zone_vehicles.

Referenced by displace_vehicle(), editmap::mapgen_preview(), rotate(), shift(), and shift_vehicle_z().

◆ update_visibility_cache()

void map::update_visibility_cache ( int  zlev)

Definition at line 5669 of file map.cpp.

5670{
5671 visibility_variables_cache.variables_set = true; // Not used yet
5672 visibility_variables_cache.g_light_level = static_cast<int>( g->light_level( zlev ) );
5673 visibility_variables_cache.vision_threshold = g->u.get_vision_threshold(
5674 get_cache_ref( g->u.posz() ).lm[g->u.posx()][g->u.posy()].max() );
5675
5676 visibility_variables_cache.u_clairvoyance = g->u.clairvoyance();
5677 visibility_variables_cache.u_sight_impaired = g->u.sight_impaired();
5679
5680 int sm_squares_seen[MAPSIZE][MAPSIZE];
5681 std::memset( sm_squares_seen, 0, sizeof( sm_squares_seen ) );
5682
5683 int min_z = fov_3d ? -OVERMAP_DEPTH : zlev;
5684 int max_z = fov_3d ? OVERMAP_HEIGHT : zlev;
5685
5686 for( int z = min_z; z <= max_z; z++ ) {
5687
5688 auto &visibility_cache = get_cache( z ).visibility_cache;
5689
5690 tripoint p;
5691 p.z = z;
5692 int &x = p.x;
5693 int &y = p.y;
5694 for( x = 0; x < MAPSIZE_X; x++ ) {
5695 for( y = 0; y < MAPSIZE_Y; y++ ) {
5697 visibility_cache[x][y] = ll;
5698 if( z == zlev ) {
5699 sm_squares_seen[ x / SEEX ][ y / SEEY ] += ( ll == lit_level::BRIGHT || ll == lit_level::LIT );
5700 }
5701 }
5702 }
5703 }
5704
5705 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
5706 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
5707 if( sm_squares_seen[gridx][gridy] > 36 ) { // 25% of the submap is visible
5708 const tripoint sm( gridx, gridy, 0 );
5709 const auto abs_sm = map::abs_sub + sm;
5710 // TODO: fix point types
5711 const tripoint_abs_omt abs_omt( sm_to_omt_copy( abs_sm ) );
5712 overmap_buffer.set_seen( abs_omt, true );
5713 }
5714 }
5715 }
5716}
lit_level apparent_light_at(const tripoint &p, const visibility_variables &cache) const
Determine the visible light level for a tile, based on light_at for the tile, vision distance,...
Definition: lightmap.cpp:729
void set_seen(const tripoint_abs_omt &p, bool seen=true)
static const efftype_id effect_boomered("boomered")
bool variables_set
Definition: map.h:122
bool u_sight_impaired
Definition: map.h:123

References abs_sub, apparent_light_at(), BRIGHT, effect_boomered, fov_3d, g, visibility_variables::g_light_level, get_cache(), get_cache_ref(), LIT, level_cache::lm, MAPSIZE, MAPSIZE_X, MAPSIZE_Y, four_quadrants::max(), my_MAPSIZE, overmap_buffer, OVERMAP_DEPTH, OVERMAP_HEIGHT, SEEX, SEEY, overmapbuffer::set_seen(), coords::sm, sm_to_omt_copy(), visibility_variables::u_clairvoyance, visibility_variables::u_is_boomered, visibility_variables::u_sight_impaired, visibility_variables::variables_set, level_cache::visibility_cache, visibility_variables_cache, visibility_variables::vision_threshold, tripoint::x, tripoint::y, and tripoint::z.

Referenced by game::draw(), draw(), game::get_player_input(), and game::look_around().

◆ use_amount()

std::list< item > map::use_amount ( const tripoint origin,
int  range,
const itype_id type,
int &  quantity,
const std::function< bool(const item &)> &  filter = return_true<item> 
)

Definition at line 4879 of file map.cpp.

4881{
4882 std::list<item> ret;
4883 for( int radius = 0; radius <= range && quantity > 0; radius++ ) {
4884 for( const tripoint &p : points_in_radius( origin, radius ) ) {
4885 if( rl_dist( origin, p ) >= radius ) {
4886 std::list<item> tmp = use_amount_square( p, type, quantity, filter );
4887 ret.splice( ret.end(), tmp );
4888 }
4889 }
4890 }
4891 return ret;
4892}
std::list< item > use_amount_square(const tripoint &p, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter=return_true< item >)
Definition: map.cpp:4857

References points_in_radius(), cata::hash64_detail::ret, rl_dist(), type, and use_amount_square().

◆ use_amount_square()

std::list< item > map::use_amount_square ( const tripoint p,
const itype_id type,
int &  quantity,
const std::function< bool(const item &)> &  filter = return_true<item> 
)

Definition at line 4857 of file map.cpp.

4859{
4860 std::list<item> ret;
4861 // Handle infinite map sources.
4862 item water = water_from( p );
4863 if( water.typeId() == type ) {
4864 ret.push_back( water );
4865 quantity = 0;
4866 return ret;
4867 }
4868
4869 if( const cata::optional<vpart_reference> vp = veh_at( p ).part_with_feature( "CARGO", true ) ) {
4870 std::list<item> tmp = use_amount_stack( vp->vehicle().get_items( vp->part_index() ), type,
4871 quantity, filter );
4872 ret.splice( ret.end(), tmp );
4873 }
4874 std::list<item> tmp = use_amount_stack( i_at( p ), type, quantity, filter );
4875 ret.splice( ret.end(), tmp );
4876 return ret;
4877}
item water_from(const tripoint &p)
Definition: map.cpp:4445
std::list< item > use_amount_stack(Stack stack, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter)
Definition: map.cpp:4843

References i_at(), cata::hash64_detail::ret, type, item::typeId(), use_amount_stack(), veh_at(), and water_from().

Referenced by use_amount().

◆ use_charges()

std::list< item > map::use_charges ( const tripoint origin,
int  range,
const itype_id type,
int &  quantity,
const std::function< bool(const item &)> &  filter = return_true<item>,
basecamp bcp = nullptr 
)

Definition at line 4977 of file map.cpp.

4980{
4981 std::list<item> ret;
4982
4983 // populate a grid of spots that can be reached
4984 std::vector<tripoint> reachable_pts;
4985 reachable_flood_steps( reachable_pts, origin, range, 1, 100 );
4986
4987 // We prefer infinite map sources where available, so search for those
4988 // first
4989 for( const tripoint &p : reachable_pts ) {
4990 // Handle infinite map sources.
4991 item water = water_from( p );
4992 if( water.typeId() == type ) {
4993 water.charges = quantity;
4994 ret.push_back( water );
4995 quantity = 0;
4996 return ret;
4997 }
4998 }
4999
5000 if( bcp ) {
5001 ret = bcp->use_charges( type, quantity );
5002 if( quantity <= 0 ) {
5003 return ret;
5004 }
5005 }
5006
5007 for( const tripoint &p : reachable_pts ) {
5008 if( has_furn( p ) ) {
5009 use_charges_from_furn( furn( p ).obj(), type, quantity, this, p, ret, filter );
5010 if( quantity <= 0 ) {
5011 return ret;
5012 }
5013 }
5014
5015 if( accessible_items( p ) ) {
5016 std::list<item> tmp = use_charges_from_stack( i_at( p ), type, quantity, p, filter );
5017 ret.splice( ret.end(), tmp );
5018 if( quantity <= 0 ) {
5019 return ret;
5020 }
5021 }
5022
5023 const optional_vpart_position vp = veh_at( p );
5024 if( !vp ) {
5025 continue;
5026 }
5027
5028 const cata::optional<vpart_reference> kpart = vp.part_with_feature( "FAUCET", true );
5029 const cata::optional<vpart_reference> weldpart = vp.part_with_feature( "WELDRIG", true );
5030 const cata::optional<vpart_reference> craftpart = vp.part_with_feature( "CRAFTRIG", true );
5031 const cata::optional<vpart_reference> forgepart = vp.part_with_feature( "FORGE", true );
5032 const cata::optional<vpart_reference> kilnpart = vp.part_with_feature( "KILN", true );
5033 const cata::optional<vpart_reference> chempart = vp.part_with_feature( "CHEMLAB", true );
5034 const cata::optional<vpart_reference> autoclavepart = vp.part_with_feature( "AUTOCLAVE", true );
5035 const cata::optional<vpart_reference> autodocpart = vp.part_with_feature( "AUTODOC", true );
5036 const cata::optional<vpart_reference> cargo = vp.part_with_feature( "CARGO", true );
5037
5038 if( kpart ) { // we have a faucet, now to see what to drain
5039 itype_id ftype = itype_id::NULL_ID();
5040
5041 // Special case hotplates which draw battery power
5042 if( type == itype_hotplate ) {
5043 ftype = itype_battery;
5044 } else {
5045 ftype = type;
5046 }
5047
5048 // TODO: add a sane birthday arg
5050 tmp.charges = kpart->vehicle().drain( ftype, quantity );
5051 // TODO: Handle water poison when crafting starts respecting it
5052 quantity -= tmp.charges;
5053 ret.push_back( tmp );
5054
5055 if( quantity == 0 ) {
5056 return ret;
5057 }
5058 }
5059
5060 if( weldpart ) { // we have a weldrig, now to see what to drain
5061 itype_id ftype = itype_id::NULL_ID();
5062
5063 if( type == itype_welder ) {
5064 ftype = itype_battery;
5065 } else if( type == itype_soldering_iron ) {
5066 ftype = itype_battery;
5067 }
5068 // TODO: add a sane birthday arg
5070 tmp.charges = weldpart->vehicle().drain( ftype, quantity );
5071 quantity -= tmp.charges;
5072 ret.push_back( tmp );
5073
5074 if( quantity == 0 ) {
5075 return ret;
5076 }
5077 }
5078
5079 if( craftpart ) { // we have a craftrig, now to see what to drain
5080 itype_id ftype = itype_id::NULL_ID();
5081
5082 if( type == itype_press ) {
5083 ftype = itype_battery;
5084 } else if( type == itype_vac_sealer ) {
5085 ftype = itype_battery;
5086 } else if( type == itype_dehydrator ) {
5087 ftype = itype_battery;
5088 } else if( type == itype_food_processor ) {
5089 ftype = itype_battery;
5090 }
5091
5092 // TODO: add a sane birthday arg
5094 tmp.charges = craftpart->vehicle().drain( ftype, quantity );
5095 quantity -= tmp.charges;
5096 ret.push_back( tmp );
5097
5098 if( quantity == 0 ) {
5099 return ret;
5100 }
5101 }
5102
5103 if( forgepart ) { // we have a veh_forge, now to see what to drain
5104 itype_id ftype = itype_id::NULL_ID();
5105
5106 if( type == itype_forge ) {
5107 ftype = itype_battery;
5108 }
5109
5110 // TODO: add a sane birthday arg
5112 tmp.charges = forgepart->vehicle().drain( ftype, quantity );
5113 quantity -= tmp.charges;
5114 ret.push_back( tmp );
5115
5116 if( quantity == 0 ) {
5117 return ret;
5118 }
5119 }
5120
5121 if( kilnpart ) { // we have a veh_kiln, now to see what to drain
5122 itype_id ftype = itype_id::NULL_ID();
5123
5124 if( type == itype_kiln ) {
5125 ftype = itype_battery;
5126 }
5127
5128 // TODO: add a sane birthday arg
5130 tmp.charges = kilnpart->vehicle().drain( ftype, quantity );
5131 quantity -= tmp.charges;
5132 ret.push_back( tmp );
5133
5134 if( quantity == 0 ) {
5135 return ret;
5136 }
5137 }
5138
5139 if( chempart ) { // we have a chem_lab, now to see what to drain
5140 itype_id ftype = itype_id::NULL_ID();
5141
5142 if( type == itype_chemistry_set ) {
5143 ftype = itype_battery;
5144 } else if( type == itype_hotplate ) {
5145 ftype = itype_battery;
5146 } else if( type == itype_electrolysis_kit ) {
5147 ftype = itype_battery;
5148 }
5149
5150 // TODO: add a sane birthday arg
5152 tmp.charges = chempart->vehicle().drain( ftype, quantity );
5153 quantity -= tmp.charges;
5154 ret.push_back( tmp );
5155
5156 if( quantity == 0 ) {
5157 return ret;
5158 }
5159 }
5160
5161 if( autoclavepart ) { // we have an autoclave, now to see what to drain
5162 itype_id ftype = itype_id::NULL_ID();
5163
5164 if( type == itype_autoclave ) {
5165 ftype = itype_battery;
5166 }
5167
5168 // TODO: add a sane birthday arg
5170 tmp.charges = autoclavepart->vehicle().drain( ftype, quantity );
5171 quantity -= tmp.charges;
5172 ret.push_back( tmp );
5173
5174 if( quantity == 0 ) {
5175 return ret;
5176 }
5177 }
5178
5179 if( cargo ) {
5180 std::list<item> tmp =
5181 use_charges_from_stack( cargo->vehicle().get_items( cargo->part_index() ), type, quantity, p,
5182 filter );
5183 ret.splice( ret.end(), tmp );
5184 if( quantity <= 0 ) {
5185 return ret;
5186 }
5187 }
5188 }
5189
5190 return ret;
5191}
std::list< item > use_charges(const itype_id &fake_id, int &quantity)
Definition: basecamp.cpp:584
bool accessible_items(const tripoint &t) const
Check whether the player can access the items located .
Definition: map.cpp:6629
void reachable_flood_steps(std::vector< tripoint > &reachable_pts, const tripoint &f, int range, int cost_min, int cost_max) const
Populates a vector of points that are reachable within a number of steps from a point.
Definition: map.cpp:6358
static const itype_id itype_autoclave("autoclave")
static void use_charges_from_furn(const furn_t &f, const itype_id &type, int &quantity, map *m, const tripoint &p, std::list< item > &ret, const std::function< bool(const item &)> &filter)
Definition: map.cpp:4909
static const itype_id itype_soldering_iron("soldering_iron")
static const itype_id itype_chemistry_set("chemistry_set")
std::list< item > use_charges_from_stack(Stack stack, const itype_id &type, int &quantity, const tripoint &pos, const std::function< bool(const item &)> &filter)
Definition: map.cpp:4895
static const itype_id itype_press("press")
static const itype_id itype_hotplate("hotplate")
static const itype_id itype_electrolysis_kit("electrolysis_kit")
static const itype_id itype_food_processor("food_processor")
static const itype_id itype_forge("forge")
static const itype_id itype_battery("battery")
static const itype_id itype_dehydrator("dehydrator")
static const itype_id itype_kiln("kiln")
static const itype_id itype_welder("welder")
static const itype_id itype_vac_sealer("vac_sealer")

References accessible_items(), item::charges, furn(), has_furn(), i_at(), itype_autoclave, itype_battery, itype_chemistry_set, itype_dehydrator, itype_electrolysis_kit, itype_food_processor, itype_forge, itype_hotplate, itype_kiln, itype_press, itype_soldering_iron, itype_vac_sealer, itype_welder, string_id< itype >::NULL_ID(), optional_vpart_position::part_with_feature(), reachable_flood_steps(), cata::hash64_detail::ret, calendar::start_of_cataclysm, type, item::typeId(), basecamp::use_charges(), use_charges_from_furn(), use_charges_from_stack(), veh_at(), and water_from().

Referenced by basecamp_action_components::consume_components(), player::consume_items(), player::consume_tools(), Character::suffer_from_asthma(), and iexamine::use_furn_fake_item().

◆ valid_move()

bool map::valid_move ( const tripoint from,
const tripoint to,
bool  bash = false,
bool  flying = false,
bool  via_ramp = false 
) const

Returns true if a creature could walk from from to to in one step.

That is, if the tiles are adjacent and either on the same z-level or connected by stairs or (in case of flying monsters) open air with no floors.

Definition at line 1919 of file map.cpp.

1921{
1922 // Used to account for the fact that older versions of GCC can trip on the if statement here.
1923 assert( to.z > std::numeric_limits<int>::min() );
1924 // Note: no need to check inbounds here, because maptile_at will do that
1925 // If oob tile is supplied, the maptile_at will be an unpassable "null" tile
1926 if( std::abs( from.x - to.x ) > 1 || std::abs( from.y - to.y ) > 1 ||
1927 std::abs( from.z - to.z ) > 1 ) {
1928 return false;
1929 }
1930
1931 if( from.z == to.z ) {
1932 // But here we need to, to prevent bashing critters
1933 return passable( to ) || ( bash && inbounds( to ) );
1934 } else if( !zlevels ) {
1935 return false;
1936 }
1937
1938 const bool going_up = from.z < to.z;
1939
1940 const tripoint &up_p = going_up ? to : from;
1941 const tripoint &down_p = going_up ? from : to;
1942
1943 const maptile up = maptile_at( up_p );
1944 const ter_t &up_ter = up.get_ter_t();
1945 if( up_ter.id.is_null() ) {
1946 return false;
1947 }
1948 // Checking for ledge is a workaround for the case when mapgen doesn't
1949 // actually make a valid ledge drop location with zlevels on, this forces
1950 // at least one zlevel drop and if down_ter is impassible it's probably
1951 // inside a wall, we could workaround that further but it's unnecessary.
1952 const bool up_is_ledge = tr_at( up_p ).loadid == tr_ledge;
1953
1954 if( up_ter.movecost == 0 ) {
1955 // Unpassable tile
1956 return false;
1957 }
1958
1959 const maptile down = maptile_at( down_p );
1960 const ter_t &down_ter = down.get_ter_t();
1961 if( down_ter.id.is_null() ) {
1962 return false;
1963 }
1964
1965 if( !up_is_ledge && down_ter.movecost == 0 ) {
1966 // Unpassable tile
1967 return false;
1968 }
1969
1970 if( !up_ter.has_flag( TFLAG_NO_FLOOR ) && !up_ter.has_flag( TFLAG_GOES_DOWN ) && !up_is_ledge &&
1971 !via_ramp ) {
1972 // Can't move from up to down
1973 if( std::abs( from.x - to.x ) == 1 || std::abs( from.y - to.y ) == 1 ) {
1974 // Break the move into two - vertical then horizontal
1975 tripoint midpoint( down_p.xy(), up_p.z );
1976 return valid_move( down_p, midpoint, bash, flying, via_ramp ) &&
1977 valid_move( midpoint, up_p, bash, flying, via_ramp );
1978 }
1979 return false;
1980 }
1981
1982 if( !flying && !down_ter.has_flag( TFLAG_GOES_UP ) && !down_ter.has_flag( TFLAG_RAMP ) &&
1983 !up_is_ledge && !via_ramp ) {
1984 // Can't safely reach the lower tile
1985 return false;
1986 }
1987
1988 if( bash ) {
1989 return true;
1990 }
1991
1992 int part_up;
1993 const vehicle *veh_up = veh_at_internal( up_p, part_up );
1994 if( veh_up != nullptr ) {
1995 // TODO: Hatches below the vehicle, passable frames
1996 return false;
1997 }
1998
1999 int part_down;
2000 const vehicle *veh_down = veh_at_internal( down_p, part_down );
2001 if( veh_down != nullptr && veh_down->roof_at_part( part_down ) >= 0 ) {
2002 // TODO: OPEN (and only open) hatches from above
2003 return false;
2004 }
2005
2006 // Currently only furniture can block movement if everything else is OK
2007 // TODO: Vehicles with boards in the given spot
2008 return up.get_furn_t().movecost >= 0;
2009}
coords::coord_point< Point, Origin, Scale > midpoint(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:562
trap_id loadid
Definition: trap.h:88

References bash(), map_data_common_t::has_flag(), ter_t::id, inbounds(), string_id< T >::is_null(), trap::loadid, maptile_at(), midpoint(), map_data_common_t::movecost, passable(), vehicle::roof_at_part(), TFLAG_GOES_DOWN, TFLAG_GOES_UP, TFLAG_NO_FLOOR, TFLAG_RAMP, tr_at(), tr_ledge, valid_move(), veh_at_internal(), tripoint::x, tripoint::xy(), tripoint::y, tripoint::z, and zlevels.

Referenced by map_funcs::climbing_cost(), combined_movecost(), explosion_handler::do_blast(), draw_critter_internal(), has_floor_or_support(), scent_map::inbounds(), iexamine::ledge(), monster::move(), process_fields_in_submap(), route(), spread_gas(), monster::stumble(), and valid_move().

◆ veh_at()

optional_vpart_position map::veh_at ( const tripoint p) const

Checks if tile is occupied by vehicle and by which part.

Parameters
pTile to check for vehicle

Definition at line 1067 of file map.cpp.

1068{
1069 if( !inbounds( p ) || !const_cast<map *>( this )->get_cache( p.z ).veh_in_active_range ) {
1071 }
1072
1073 int part_num = 1;
1074 vehicle *const veh = const_cast<map *>( this )->veh_at_internal( p, part_num );
1075 if( !veh ) {
1077 }
1078 return optional_vpart_position( vpart_position( *veh, part_num ) );
1079
1080}
static constexpr nullopt_t nullopt
Definition: optional.h:22

References get_cache(), inbounds(), cata::nullopt, veh_at_internal(), level_cache::veh_in_active_range, and tripoint::z.

Referenced by Character::activate_bionic(), activity_on_turn_move_loot(), zone_manager::add(), add_splatter(), add_vehicle_to_map(), apply_faction_ownership(), are_requirements_nearby(), Creature::auto_find_hostile_target(), character_funcs::base_comfort_value(), bash(), bash_rating(), bash_vehicle(), board_vehicle(), build_seen_cache(), build_vision_transparency_cache(), VehicleSpawnFunction::builtin_parkinglot(), Character::burn_fuel(), can_do_activity_there(), can_examine_at(), can_interact_at(), can_pickup_at(), can_put_items(), can_use_bipod(), check_art_charge_req(), vehicle::autodrive_controller::check_drivable(), player::check_eligible_containers_for_crafting(), construct::check_empty(), vehicle::check_heli_ascend(), vehicle::check_heli_descend(), activity_handlers::chop_tree_finish(), climb_difficulty(), doors::close_door(), veh_interact::complete_vehicle(), game::control_vehicle(), coverage(), creature_in_field(), crush(), cycle_action(), debug_menu::debug(), deregister_vehicle_zone(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::discharge_real_power_source(), explosion_handler::do_blast(), game::do_turn(), editmap_hilight::draw(), editmap::draw_main_ui_overlay(), drop_vehicle(), game::examine(), npc::execute_action(), ranged::expected_coverage(), fetch_activity(), activity_handlers::fill_liquid_do_turn(), find_auto_consume(), npc::find_item(), Character::find_remote_fuel(), fire(), ranged::fire_gun(), game::fling_creature(), Character::floor_bedding_warmth(), Character::floor_item_warmth(), game::forced_door_closing(), inventory::form_from_map(), generic_multi_activity_check_requirement(), avatar::get_book_reader(), item::get_cable_target(), game::get_dangerous_tile(), player::get_eligible_containers_for_crafting(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::get_fake_tool(), liquid_handler::get_liquid_target(), overmap_ui::get_overmap_path_to(), game::get_veh_dir_indicator_location(), grab(), game::grabbed_furn_move(), game::grabbed_veh_move(), ranged::gunmode_checks_common(), ranged::gunmode_checks_weapon(), handbrake(), game::handle_action(), handle_action_menu(), Character::has_alarm_clock(), has_flag_vpart(), has_nearby_chair(), has_nearby_table(), jmapgen_setmap::has_vehicle_collision(), mapgen_function_json_base::has_vehicle_collision(), jmapgen_alternativly< PieceType >::has_vehicle_collision(), jmapgen_sign::has_vehicle_collision(), jmapgen_vending_machine::has_vehicle_collision(), jmapgen_toilet::has_vehicle_collision(), jmapgen_gaspump::has_vehicle_collision(), jmapgen_vehicle::has_vehicle_collision(), jmapgen_trap::has_vehicle_collision(), jmapgen_furniture::has_vehicle_collision(), jmapgen_terrain::has_vehicle_collision(), jmapgen_computer::has_vehicle_collision(), jmapgen_sealed_item::has_vehicle_collision(), Character::has_watch(), haul(), Character::in_climate_control(), advanced_inv_area::init(), is_bashable(), is_driving(), weather::is_sheltered(), Character::is_snuggling(), game::load(), make_active(), mine_activity(), monster_in_field(), mop_spills(), avatar_action::move(), move_cost(), npc::move_to(), move_vehicle(), game::moving_vehicle_dismount(), MapExtras::mx_helicopter(), obstacle_coverage(), obstacle_name(), open(), open_door(), vehicle::part_collision(), Character::passive_power_gen(), liquid_handler::perform_liquid_transfer(), game::phasing_move(), npc::pick_up_item(), game::place_player(), player_in_field(), pldrive(), game::print_all_tile_info(), item::process_cable(), item::process_extinguish(), projectile_attack(), vehicle_part::properties_to_item(), put_into_vehicle_or_drop(), game::remoteveh(), DefaultRemovePartHandler::removed(), zone_manager::revert_vzones(), iexamine::rubble(), conditional_t< T >::set_is_driving(), set_item_map_or_vehicle(), shoot(), explosion_handler::shrapnel(), iexamine::shrub_wildveggies(), spell_effect::spawn_summoned_vehicle(), autodrive_activity_actor::start(), activity_handlers::start_engines_finish(), supports_above(), game::swap_critters(), avatar_action::swim(), rot::temperature_flag_for_location(), tidy_activity(), avatar_funcs::try_to_sleep(), unboard_vehicle(), Character::update_bodytemp(), editmap::update_view_with_help(), deploy_furn_actor::use(), deploy_tent_actor::use(), use_amount_square(), use_charges(), game::validate_linked_vehicles(), vehicle_activity(), activity_handlers::vehicle_finish(), vehicle_selector::vehicle_selector(), wait(), game::walk_move(), avatar_action::wield(), and workbench_crafting_speed_multiplier().

◆ veh_at_internal() [1/2]

vehicle * map::veh_at_internal ( const tripoint p,
int &  part_num 
)

Definition at line 1102 of file map.cpp.

1103{
1104 return const_cast<vehicle *>( const_cast<const map *>( this )->veh_at_internal( p, part_num ) );
1105}

References veh_at_internal().

Referenced by draw_from_above(), draw_maptile(), process_fields_in_submap(), route(), update_pathfinding_cache(), valid_move(), veh_at(), and veh_at_internal().

◆ veh_at_internal() [2/2]

const vehicle * map::veh_at_internal ( const tripoint p,
int &  part_num 
) const

Definition at line 1082 of file map.cpp.

1083{
1084 // This function is called A LOT. Move as much out of here as possible.
1085 const level_cache &ch = get_cache( p.z );
1086 if( !ch.veh_in_active_range || !ch.veh_exists_at[p.x][p.y] ) {
1087 part_num = -1;
1088 return nullptr; // Clear cache indicates no vehicle. This should optimize a great deal.
1089 }
1090
1091 const auto it = ch.veh_cached_parts.find( p );
1092 if( it != ch.veh_cached_parts.end() ) {
1093 part_num = it->second.second;
1094 return it->second.first;
1095 }
1096
1097 debugmsg( "vehicle part cache indicated vehicle not found: %d %d %d", p.x, p.y, p.z );
1098 part_num = -1;
1099 return nullptr;
1100}

References debugmsg, get_cache(), level_cache::veh_cached_parts, level_cache::veh_exists_at, level_cache::veh_in_active_range, tripoint::x, tripoint::y, and tripoint::z.

◆ vehicle_vehicle_collision()

float map::vehicle_vehicle_collision ( vehicle veh,
vehicle veh2,
const std::vector< veh_collision > &  collisions 
)

Definition at line 820 of file map.cpp.

822{
823 if( &veh == &veh2 ) {
824 debugmsg( "Vehicle %s collided with itself", veh.name );
825 return 0.0f;
826 }
827
828 // Effects of colliding with another vehicle:
829 // transfers of momentum, skidding,
830 // parts are damaged/broken on both sides,
831 // remaining times are normalized
832 const veh_collision &c = collisions[0];
833 add_msg( m_bad, _( "The %1$s's %2$s collides with %3$s's %4$s." ),
834 veh.name, veh.part_info( c.part ).name(),
835 veh2.name, veh2.part_info( c.target_part ).name() );
836
837 const bool vertical = veh.sm_pos.z != veh2.sm_pos.z;
838
839 // Used to calculate the epicenter of the collision.
840 point epicenter1;
841 point epicenter2;
842
843 float dmg;
844 // Vertical collisions will be simpler for a while (1D)
845 if( !vertical ) {
846 // For reference, a cargo truck weighs ~25300, a bicycle 690,
847 // and 38mph is 3800 'velocity'
848 rl_vec2d velo_veh1 = veh.velo_vec();
849 rl_vec2d velo_veh2 = veh2.velo_vec();
850 const float m1 = to_kilogram( veh.total_mass() );
851 const float m2 = to_kilogram( veh2.total_mass() );
852 //Energy of vehicle1 and vehicle2 before collision
853 float E = 0.5 * m1 * velo_veh1.magnitude() * velo_veh1.magnitude() +
854 0.5 * m2 * velo_veh2.magnitude() * velo_veh2.magnitude();
855
856 // Collision_axis
857 point cof1 = veh .rotated_center_of_mass();
858 point cof2 = veh2.rotated_center_of_mass();
859 int &x_cof1 = cof1.x;
860 int &y_cof1 = cof1.y;
861 int &x_cof2 = cof2.x;
862 int &y_cof2 = cof2.y;
863 rl_vec2d collision_axis_y;
864
865 collision_axis_y.x = ( veh.global_pos3().x + x_cof1 ) - ( veh2.global_pos3().x + x_cof2 );
866 collision_axis_y.y = ( veh.global_pos3().y + y_cof1 ) - ( veh2.global_pos3().y + y_cof2 );
867 collision_axis_y = collision_axis_y.normalized();
868 rl_vec2d collision_axis_x = collision_axis_y.rotated( M_PI / 2 );
869 // imp? & delta? & final? reworked:
870 // newvel1 =( vel1 * ( mass1 - mass2 ) + ( 2 * mass2 * vel2 ) ) / ( mass1 + mass2 )
871 // as per http://en.wikipedia.org/wiki/Elastic_collision
872 //velocity of veh1 before collision in the direction of collision_axis_y
873 float vel1_y = collision_axis_y.dot_product( velo_veh1 );
874 float vel1_x = collision_axis_x.dot_product( velo_veh1 );
875 //velocity of veh2 before collision in the direction of collision_axis_y
876 float vel2_y = collision_axis_y.dot_product( velo_veh2 );
877 float vel2_x = collision_axis_x.dot_product( velo_veh2 );
878 // e = 0 -> inelastic collision
879 // e = 1 -> elastic collision
880 float e = get_collision_factor( vel1_y / 100 - vel2_y / 100 );
881
882 // Velocity after collision
883 // vel1_x_a = vel1_x, because in x-direction we have no transmission of force
884 float vel1_x_a = vel1_x;
885 float vel2_x_a = vel2_x;
886 // Transmission of force only in direction of collision_axix_y
887 // Equation: partially elastic collision
888 float vel1_y_a = ( m2 * vel2_y * ( 1 + e ) + vel1_y * ( m1 - m2 * e ) ) / ( m1 + m2 );
889 float vel2_y_a = ( m1 * vel1_y * ( 1 + e ) + vel2_y * ( m2 - m1 * e ) ) / ( m1 + m2 );
890 // Add both components; Note: collision_axis is normalized
891 rl_vec2d final1 = collision_axis_y * vel1_y_a + collision_axis_x * vel1_x_a;
892 rl_vec2d final2 = collision_axis_y * vel2_y_a + collision_axis_x * vel2_x_a;
893
894 veh.move.init( final1.as_point() );
895 if( final1.dot_product( veh.face_vec() ) < 0 ) {
896 // Car is being pushed backwards. Make it move backwards
897 veh.velocity = -final1.magnitude();
898 } else {
899 veh.velocity = final1.magnitude();
900 }
901
902 veh2.move.init( final2.as_point() );
903 if( final2.dot_product( veh2.face_vec() ) < 0 ) {
904 // Car is being pushed backwards. Make it move backwards
905 veh2.velocity = -final2.magnitude();
906 } else {
907 veh2.velocity = final2.magnitude();
908 }
909
910 //give veh2 the initiative to proceed next before veh1
911 float avg_of_turn = ( veh2.of_turn + veh.of_turn ) / 2;
912 if( avg_of_turn < .1f ) {
913 avg_of_turn = .1f;
914 }
915
916 veh.of_turn = avg_of_turn * .9;
917 veh2.of_turn = avg_of_turn * 1.1;
918
919 //Energy after collision
920 float E_a = 0.5 * m1 * final1.magnitude() * final1.magnitude() +
921 0.5 * m2 * final2.magnitude() * final2.magnitude();
922 float d_E = E - E_a; //Lost energy at collision -> deformation energy
923 dmg = std::abs( d_E / 1000 / 2000 ); //adjust to balance damage
924 } else {
925 const float m1 = to_kilogram( veh.total_mass() );
926 // Collision is perfectly inelastic for simplicity
927 // Assume veh2 is standing still
928 dmg = std::abs( veh.vertical_velocity / 100 ) * m1 / 10;
929 veh.vertical_velocity = 0;
930 }
931
932 float dmg_veh1 = dmg * 0.5;
933 float dmg_veh2 = dmg * 0.5;
934
935 int coll_parts_cnt = 0; //quantity of colliding parts between veh1 and veh2
936 for( const auto &veh_veh_coll : collisions ) {
937 if( &veh2 == static_cast<vehicle *>( veh_veh_coll.target ) ) {
938 coll_parts_cnt++;
939 }
940 }
941
942 const float dmg1_part = dmg_veh1 / coll_parts_cnt;
943 const float dmg2_part = dmg_veh2 / coll_parts_cnt;
944
945 //damage colliding parts (only veh1 and veh2 parts)
946 for( const auto &veh_veh_coll : collisions ) {
947 if( &veh2 != static_cast<vehicle *>( veh_veh_coll.target ) ) {
948 continue;
949 }
950
951 int parm1 = veh.part_with_feature( veh_veh_coll.part, VPFLAG_ARMOR, true );
952 if( parm1 < 0 ) {
953 parm1 = veh_veh_coll.part;
954 }
955 int parm2 = veh2.part_with_feature( veh_veh_coll.target_part, VPFLAG_ARMOR, true );
956 if( parm2 < 0 ) {
957 parm2 = veh_veh_coll.target_part;
958 }
959
960 epicenter1 += veh.part( parm1 ).mount;
961 veh.damage( parm1, dmg1_part, DT_BASH );
962
963 epicenter2 += veh2.part( parm2 ).mount;
964 veh2.damage( parm2, dmg2_part, DT_BASH );
965 }
966
967 epicenter2.x /= coll_parts_cnt;
968 epicenter2.y /= coll_parts_cnt;
969
970 if( dmg2_part > 100 ) {
971 // Shake vehicle because of collision
972 veh2.damage_all( dmg2_part / 2, dmg2_part, DT_BASH, epicenter2 );
973 }
974
975 if( dmg_veh1 > 800 ) {
976 veh.skidding = true;
977 }
978
979 if( dmg_veh2 > 800 ) {
980 veh2.skidding = true;
981 }
982
983 // Return the impulse of the collision
984 return dmg_veh1;
985}
point rotated_center_of_mass() const
Definition: vehicle.cpp:3328
rl_vec2d face_vec() const
rl_vec2d velo_vec() const
float of_turn
Definition: vehicle.h:1956
std::string name() const
Translated name of a part.
Definition: veh_type.cpp:700
#define M_PI
Definition: math_defines.h:21
point as_point() const
Definition: line.cpp:686
rl_vec2d rotated(float angle) const
Definition: line.cpp:647
float magnitude() const
Definition: line.cpp:610
rl_vec2d normalized() const
Definition: line.cpp:620
float y
Definition: point_float.h:13
float x
Definition: point_float.h:12
float dot_product(const rl_vec2d &v) const
Definition: line.cpp:664
@ VPFLAG_ARMOR
Definition: veh_type.h:32
float get_collision_factor(float delta_v)

References _, add_msg(), rl_vec2d::as_point(), c, vehicle::damage(), vehicle::damage_all(), debugmsg, rl_vec2d::dot_product(), DT_BASH, vehicle::face_vec(), get_collision_factor(), vehicle::global_pos3(), tileray::init(), m_bad, M_PI, rl_vec2d::magnitude(), vehicle_part::mount, vehicle::move, vpart_info::name(), vehicle::name, rl_vec2d::normalized(), vehicle::of_turn, vehicle::part(), vehicle::part_info(), vehicle::part_with_feature(), rl_vec2d::rotated(), vehicle::rotated_center_of_mass(), vehicle::skidding, vehicle::sm_pos, units::to_kilogram(), vehicle::total_mass(), vehicle::velo_vec(), vehicle::velocity, vehicle::vertical_velocity, VPFLAG_ARMOR, point::x, tripoint::x, rl_vec2d::x, point::y, tripoint::y, rl_vec2d::y, and tripoint::z.

Referenced by move_vehicle().

◆ vehicle_wheel_traction()

float map::vehicle_wheel_traction ( const vehicle veh,
bool  ignore_movement_modifiers = false 
) const

Definition at line 1586 of file vehicle_move.cpp.

1588{
1589 if( veh.is_in_water( true ) ) {
1590 return veh.can_float() ? 1.0f : -1.0f;
1591 }
1592 if( veh.is_in_water() && veh.is_watercraft() && veh.can_float() ) {
1593 return 1.0f;
1594 }
1595
1596 const auto &wheel_indices = veh.wheelcache;
1597 int num_wheels = wheel_indices.size();
1598 if( num_wheels == 0 ) {
1599 // TODO: Assume it is digging in dirt
1600 // TODO: Return something that could be reused for dragging
1601 return 0.0f;
1602 }
1603
1604 float traction_wheel_area = 0.0f;
1605
1606 if( vehicle_movement::is_on_rails( *this, veh ) ) {
1607 // Vehicles on rails are considered to have all of their wheels on rails
1608 for( int p : veh.rail_wheelcache ) {
1609 traction_wheel_area += veh.cpart( p ).wheel_area();
1610 }
1611 return traction_wheel_area;
1612 }
1613
1614 for( int p : wheel_indices ) {
1615 const tripoint &pp = veh.global_part_pos3( p );
1616 const int wheel_area = veh.cpart( p ).wheel_area();
1617
1618 const auto &tr = ter( pp ).obj();
1619 // Deep water and air
1620 if( tr.has_flag( TFLAG_DEEP_WATER ) || tr.has_flag( TFLAG_NO_FLOOR ) ) {
1621 // No traction from wheel in water or air
1622 continue;
1623 }
1624
1625 int move_mod = move_cost_ter_furn( pp );
1626 if( move_mod == 0 ) {
1627 // Vehicle locked in wall
1628 // Shouldn't happen, but does
1629 return 0.0f;
1630 }
1631
1632 for( const auto &terrain_mod : veh.part_info( p ).wheel_terrain_mod() ) {
1633 if( !tr.has_flag( terrain_mod.first ) ) {
1634 move_mod += terrain_mod.second;
1635 break;
1636 }
1637 }
1638
1639 // Ignore the movement modifier if needed.
1640 if( ignore_movement_modifiers ) {
1641 move_mod = 2;
1642 }
1643
1644 traction_wheel_area += 2.0 * wheel_area / move_mod;
1645 }
1646
1647 return traction_wheel_area;
1648}
bool is_watercraft() const
Definition: vehicle.cpp:4218
std::vector< int > rail_wheelcache
Definition: vehicle.h:1845
bool can_float() const
can_float does the vehicle have freeboard or does it overflow with water?
Definition: vehicle.cpp:4155
std::vector< std::pair< std::string, int > > wheel_terrain_mod() const
Definition: veh_type.cpp:898
bool is_on_rails(const map &m, const vehicle &veh)
Returns whether the vehicle is currently on rails.

References vehicle::can_float(), vehicle::cpart(), vehicle::global_part_pos3(), vehicle::is_in_water(), vehicle_movement::is_on_rails(), vehicle::is_watercraft(), move_cost_ter_furn(), int_id< T >::obj(), vehicle::part_info(), vehicle::rail_wheelcache, ter(), TFLAG_DEEP_WATER, TFLAG_NO_FLOOR, vehicle_part::wheel_area(), vpart_info::wheel_terrain_mod(), and vehicle::wheelcache.

Referenced by vehicle::act_on_map(), and move_vehicle().

◆ vehmove()

void map::vehmove ( )

Definition at line 472 of file map.cpp.

473{
474 // give vehicles movement points
475 VehicleList vehicle_list;
476 int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
477 int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
478 for( int zlev = minz; zlev <= maxz; ++zlev ) {
479 level_cache &cache = get_cache( zlev );
480 for( vehicle *veh : cache.vehicle_list ) {
481 veh->gain_moves();
482 veh->slow_leak();
484 w.v = veh;
485 vehicle_list.push_back( w );
486 }
487 }
488
489 // 15 equals 3 >50mph vehicles, or up to 15 slow (1 square move) ones
490 // But 15 is too low for V12 death-bikes, let's put 100 here
491 for( int count = 0; count < 100; count++ ) {
492 if( !vehproceed( vehicle_list ) ) {
493 break;
494 }
495 }
496 // Process item removal on the vehicles that were modified this turn.
497 // Use a copy because part_removal_cleanup can modify the container.
498 auto temp = dirty_vehicle_list;
499 for( const auto &elem : temp ) {
500 auto same_ptr = [ elem ]( const struct wrapped_vehicle & tgt ) {
501 return elem == tgt.v;
502 };
503 if( std::find_if( vehicle_list.begin(), vehicle_list.end(), same_ptr ) !=
504 vehicle_list.end() ) {
505 elem->part_removal_cleanup();
506 }
507 }
508 dirty_vehicle_list.clear();
509 // The bool tracks whether the vehicles is on the map or not.
510 std::map<vehicle *, bool> connected_vehicles;
511 for( int zlev = minz; zlev <= maxz; ++zlev ) {
512 level_cache &cache = get_cache( zlev );
513 vehicle::enumerate_vehicles( connected_vehicles, cache.vehicle_list );
514 }
515 for( std::pair<vehicle *const, bool> &veh_pair : connected_vehicles ) {
516 veh_pair.first->idle( veh_pair.second );
517 }
518}
bool vehproceed(VehicleList &vehicle_list)
Definition: map.cpp:520
static void enumerate_vehicles(std::map< vehicle *, bool > &connected_vehicles, const std::set< vehicle * > &vehicle_list)
Use grid traversal to enumerate all connected vehicles.
Definition: vehicle.cpp:4929
void slow_leak()
Definition: vehicle.cpp:5296
void gain_moves()
Definition: vehicle.cpp:5543

References abs_sub, detail::count(), dirty_vehicle_list, vehicle::enumerate_vehicles(), vehicle::gain_moves(), get_cache(), OVERMAP_DEPTH, OVERMAP_HEIGHT, vehicle::slow_leak(), wrapped_vehicle::v, level_cache::vehicle_list, vehproceed(), tripoint::z, and zlevels.

Referenced by game::do_turn().

◆ vehproceed()

bool map::vehproceed ( VehicleList vehicle_list)

Definition at line 520 of file map.cpp.

521{
522 wrapped_vehicle *cur_veh = nullptr;
523 float max_of_turn = 0;
524 // First horizontal movement
525 for( wrapped_vehicle &vehs_v : vehicle_list ) {
526 if( vehs_v.v->of_turn > max_of_turn ) {
527 cur_veh = &vehs_v;
528 max_of_turn = cur_veh->v->of_turn;
529 }
530 }
531
532 // Then vertical-only movement
533 if( cur_veh == nullptr ) {
534 for( wrapped_vehicle &vehs_v : vehicle_list ) {
535 if( vehs_v.v->is_falling || ( vehs_v.v->is_rotorcraft() && vehs_v.v->get_z_change() != 0 ) ) {
536 cur_veh = &vehs_v;
537 break;
538 }
539 }
540 }
541
542 if( cur_veh == nullptr ) {
543 return false;
544 }
545
546 cur_veh->v = cur_veh->v->act_on_map();
547 if( cur_veh->v == nullptr ) {
548 vehicle_list = get_vehicles();
549 }
550
551 // confirm that veh_in_active_range is still correct for each z-level
552 int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
553 int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
554 for( int zlev = minz; zlev <= maxz; ++zlev ) {
555 level_cache &cache = get_cache( zlev );
556
557 // Check if any vehicles exist in the active range for this z-level
559 std::any_of( std::begin( cache.veh_exists_at ),
560 std::end( cache.veh_exists_at ), []( const auto & row ) {
561 return std::any_of( std::begin( row ), std::end( row ), []( bool veh_exists ) {
562 return veh_exists;
563 } );
564 } );
565 }
566
567 return true;
568}
vehicle * act_on_map()

References abs_sub, vehicle::act_on_map(), get_cache(), get_vehicles(), vehicle::of_turn, OVERMAP_DEPTH, OVERMAP_HEIGHT, wrapped_vehicle::v, level_cache::veh_exists_at, level_cache::veh_in_active_range, tripoint::z, and zlevels.

Referenced by vehmove().

◆ vertical_shift()

void map::vertical_shift ( int  newz)

Moves the map vertically to (not by!) newz.

Does not actually shift anything, only forces cache updates. In the future, it will either actually shift the map or it will get removed after 3D migration is complete.

Definition at line 6983 of file map.cpp.

6984{
6985 if( !zlevels ) {
6986 debugmsg( "Called map::vertical_shift in a non-z-level world" );
6987 return;
6988 }
6989
6990 if( newz < -OVERMAP_DEPTH || newz > OVERMAP_HEIGHT ) {
6991 debugmsg( "Tried to get z-level %d outside allowed range of %d-%d",
6992 newz, -OVERMAP_DEPTH, OVERMAP_HEIGHT );
6993 return;
6994 }
6995
6996 tripoint trp = get_abs_sub();
6997 set_abs_sub( tripoint( trp.xy(), newz ) );
6998
6999 // TODO: Remove the function when it's safe
7000 return;
7001}

References debugmsg, get_abs_sub(), OVERMAP_DEPTH, OVERMAP_HEIGHT, set_abs_sub(), tripoint::xy(), and zlevels.

Referenced by game::vertical_shift().

◆ water_from()

item map::water_from ( const tripoint p)

Definition at line 4445 of file map.cpp.

4446{
4447 if( has_flag( "SALT_WATER", p ) ) {
4449 }
4450
4451 const ter_id terrain_id = ter( p );
4452 if( terrain_id == t_sewage ) {
4454 ret.poison = rng( 1, 7 );
4455 return ret;
4456 }
4457
4459 // iexamine::water_source requires a valid liquid from this function.
4460 if( terrain_id.obj().examine == &iexamine::water_source ) {
4461 int poison_chance = 0;
4462 if( terrain_id.obj().has_flag( TFLAG_DEEP_WATER ) ) {
4463 if( terrain_id.obj().has_flag( TFLAG_CURRENT ) ) {
4464 poison_chance = 20;
4465 } else {
4466 poison_chance = 4;
4467 }
4468 } else {
4469 if( terrain_id.obj().has_flag( TFLAG_CURRENT ) ) {
4470 poison_chance = 10;
4471 } else {
4472 poison_chance = 3;
4473 }
4474 }
4475 if( one_in( poison_chance ) ) {
4476 ret.poison = rng( 1, 4 );
4477 }
4478 return ret;
4479 }
4480 if( furn( p ).obj().examine == &iexamine::water_source ) {
4481 return ret;
4482 }
4483 return item();
4484}
static const int INFINITE_CHARGES
Definition: item.h:2155
void examine(Character &p, const tripoint &pos)
Calls the examine function of furniture or terrain at given tile, for given character.
Definition: map.cpp:1678
@ TFLAG_CURRENT
Definition: mapdata.h:302
void water_source(player &p, const tripoint &examp)
Definition: iexamine.cpp:3869

References examine(), map_data_common_t::examine, furn(), map_data_common_t::has_flag(), has_flag(), item::INFINITE_CHARGES, int_id< T >::obj(), one_in(), cata::hash64_detail::ret, rng(), calendar::start_of_cataclysm, t_sewage, ter(), TFLAG_CURRENT, TFLAG_DEEP_WATER, and iexamine::water_source().

Referenced by inventory::form_from_map(), use_amount_square(), use_charges(), and iexamine::water_source().

Friends And Related Function Documentation

◆ editmap

friend class editmap
friend

Definition at line 385 of file map.h.

◆ visitable< map_cursor >

friend class visitable< map_cursor >
friend

Definition at line 385 of file map.h.

Member Data Documentation

◆ abs_sub

tripoint map::abs_sub
protected

Absolute coordinates of first submap (get_submap_at(0,0)) This is in submap coordinates (see overmapbuffer for explanation).

It is set upon:

  • loading submap at grid[0],
  • generating submaps (generate)
  • shifting the map with shift

Definition at line 1784 of file map.h.

Referenced by add_item(), add_item_or_charges(), add_vehicle(), adjust_radiation(), apply_faction_ownership(), bash_rating(), bash_resistance(), bash_strength(), build_floor_caches(), can_put_items(), can_put_items_ter_furn(), check_submap_active_item_consistency(), clear_vehicle_cache(), create_anomaly(), decay_fields_and_scent(), detach_vehicle(), draw_fill_background(), draw_lab(), draw_mine(), draw_temple(), draw_triffid(), features(), furn(), furn_set(), furnname(), generate(), get_abs_sub(), get_active_items_in_radius(), get_nonant(), get_submap_at(), get_vehicles(), getabs(), getlocal(), has_flag(), has_flag_furn(), has_flag_ter(), has_flag_ter_or_furn(), has_furn(), i_at(), i_clear(), i_rem(), is_bashable(), is_bashable_furn(), is_bashable_ter(), is_bashable_ter_furn(), is_divable(), is_outside(), is_water_shallow_current(), loadn(), make_active(), move_cost(), move_cost_ter_furn(), name(), passable(), place_items(), place_npc(), place_vending(), points_on_zlevel(), process_fields(), process_fields_in_submap(), process_items(), reset_vehicle_cache(), rotate(), save(), saven(), scent_blockers(), set_abs_sub(), set_radiation(), set_temperature(), spawn_an_item(), spawn_item(), spawn_items(), spawn_monsters(), spawn_monsters_submap(), spawn_monsters_submap_group(), ter(), ter_set(), tername(), update_submap_active_item_status(), update_visibility_cache(), vehmove(), and vehproceed().

◆ caches

std::array< std::unique_ptr<level_cache>, OVERMAP_LAYERS > map::caches
private

Holds caches for visibility, light, transparency and vehicles.

Definition at line 1956 of file map.h.

Referenced by access_cache(), get_cache(), get_cache_ref(), and map().

◆ dirty_vehicle_list

◆ field_furn_locs

std::vector<tripoint> map::field_furn_locs
private

Vector of tripoints containing active field-emitting furniture.

Definition at line 1952 of file map.h.

Referenced by actualize(), furn_set(), get_furn_field_locations(), load(), and shift_traps().

◆ grid

std::vector<submap *> map::grid
private

The list of currently loaded submaps.

The size of this should not be changed. After calling load or generate, it should only contain non-null pointers. Use getsubmap or setsubmap to access it.

Definition at line 1941 of file map.h.

Referenced by actualize(), add_roofs(), clear_spawns(), clear_traps(), editmap::cleartmpmap(), displace_vehicle(), getsubmap(), loadn(), map(), saven(), and setsubmap().

◆ last_full_vehicle_list

VehicleList map::last_full_vehicle_list
private

Vehicle list doesn't change often, but is pretty expensive.

Definition at line 1972 of file map.h.

Referenced by get_vehicles().

◆ last_full_vehicle_list_dirty

bool map::last_full_vehicle_list_dirty = true
private

◆ max_populated_zlev

cata::optional<std::pair<tripoint, int> > map::max_populated_zlev = cata::nullopt
private

Definition at line 1986 of file map.h.

Referenced by calc_max_populated_zlev(), and invalidate_max_populated_zlev().

◆ my_MAPSIZE

◆ pathfinding_caches

std::array< std::unique_ptr<pathfinding_cache>, OVERMAP_LAYERS > map::pathfinding_caches
mutableprivate

Definition at line 1958 of file map.h.

Referenced by get_pathfinding_cache(), get_pathfinding_cache_ref(), and map().

◆ skew_vision_cache

lru_cache<point, char> map::skew_vision_cache
mutableprivate

Cache of coordinate pairs recently checked for visibility.

Definition at line 1967 of file map.h.

Referenced by build_map_cache(), and sees().

◆ submaps_with_active_items

std::set<tripoint> map::submaps_with_active_items
private

◆ support_cache_dirty

std::set<tripoint> map::support_cache_dirty
private

Definition at line 1491 of file map.h.

Referenced by process_falling(), shift(), support_dirty(), and ter_set().

◆ traplocs

std::vector< std::vector<tripoint> > map::traplocs
private

This vector contains an entry for each trap type, it has therefor the same size as the traplist vector.

Each entry contains a list of all point on the map that contain a trap of that type. The first entry however is always empty as it denotes the tr_null trap.

Definition at line 1948 of file map.h.

Referenced by actualize(), clear_traps(), load(), map(), remove_trap(), shift_traps(), ter_set(), trap_locations(), and trap_set().

◆ visibility_variables_cache

visibility_variables map::visibility_variables_cache
private

Definition at line 1982 of file map.h.

Referenced by get_visibility_variables_cache(), and update_visibility_cache().

◆ vision_transparency_cache

vision_adjustment map::vision_transparency_cache[8] = { VISION_ADJUST_NONE }
protected

Definition at line 1774 of file map.h.

Referenced by apply_vision_transparency_cache(), and build_vision_transparency_cache().

◆ zlevels


The documentation for this class was generated from the following files: